栈与队列的学习与初应用

概念不多说,上题目。

codeup 1918 简易计算器
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:

30 / 90 - 26 + 97 - 5 - 6 - 13 / 88 * 6 + 51 / 29 + 79 * 87 + 57 * 92
0

1
2
3
样例输出:

12178.21

————————————————

主要思路

1.用栈将中缀表达式转化为后缀表达式,进入队列

2.计算后缀表达式

#include<bits/stdc++.h>
using namespace std;
struct node
{
    double num;//记录数字
    char op;//记录运算符
    bool flag;//标记为数字还是计算符
};
string str;
stack<node> s;
queue<node> q;
map<char,int> op;//标记运算符优先级(operator)
void change()
{
    node temp;
    for(int i=0;i<str.size();)
    {
        if(str[i]>='0'&&str[i]<='9')//数字进队列
        {
            temp.flag=true;//标记为数字
            temp.num=str[i++]-'0';//记录数字后i自增
            while(i<str.size()&&str[i]>='0'&&str[i]<='9')//提前检测下一位,防止为两位数
            {
                temp.num=temp.num*10+(str[i]-'0');
                i++;//自增
            }
            q.push(temp);//进队
        }
        else
        {
            temp.flag=false;//同理
            while(!s.empty()&&op[str[i]]<=op[s.top().op])//与栈顶元素比较
            {
                q.push(s.top());//若该元素不高于栈顶元素,弹出栈顶元素(如,栈中为“/”,比较元素为“+”,显然栈中优先级更高,所以“/”在队列中位置较‘+’更靠前)
                s.pop();//为什么是不高于而不是低于,因为当优先级相同时,谁靠前谁先算,越靠前的越先进栈,所以弹出栈进队
            }
            //这里的思想只需要记住一点,队列的符号排列顺序即为使用顺序,所以越先进队越先计算,用栈留住优先级低的(同级则为留住靠后,靠后的符号)
            temp.op=str[i];
            s.push(temp);//为优先级更高的符号,则直接进队
            i++;//i自增
        }
    } 
    while(!s.empty())//防止遗漏元素
    {
        q.push(s.top());
        s.pop();
    }
} 
double cal()
{
    double temp1,temp2;
    node cur,temp;
    while(!q.empty())//队列不空
    {
        cur=q.front();//队首元素赋给cur
        q.pop();//赋完元素要出队
        if(cur.flag) //如果为数字,则直接进栈
        {
            s.push(cur);
        }
        else 
        {
            temp2=s.top().num;//注意这里的进栈,因为减法除法使用的两个数顺序不能颠倒,则先进栈的后出栈,所以先出栈的给temp2
            s.pop();
            temp1=s.top().num;
            s.pop();
            temp.flag=true;
            if(cur.op=='+') temp.num=temp1+temp2;//四则运算
            else if(cur.op=='-') temp.num=temp1-temp2;
            else if(cur.op=='*') temp.num=temp1*temp2;
            else  temp.num=temp1/temp2;
            s.push(temp);//每次计算完之后再进栈,即为先计算完的部分,可以视为一个数与剩余部分计算
        }
    }
    return s.top().num;
}
int main()
{
    op['+']=op['-']=1;
    op['*']=op['/']=2;//map标记符号,用数字代表优先级
    while(getline(cin,str),str!="0")//未知数据组数
    {
        for(string::iterator it=str.end();it!=str.begin();it--)
        {
            if(*it==' ') str.erase(it);//删除多余空格(如果题干有说明会出现无效字符此处一并删除即可)
        }
        while(!s.empty()) s.pop();//栈初始化
        change();
        printf("%.2lf\n",cal());
    }
    return 0;
}

算法小白,一起努力吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值