简单计算器 逆波兰表达式

问题 C: 悠派计算器

时间限制: 1 Sec  内存限制: 128 MB
提交: 7  解决: 2
[提交][状态][讨论版][命题人:qianyouyou]

题目描述

yoyo的小老弟小渣渣灰特别懒,兴趣爱好并不多,就睡觉一个。为了多睡会儿懒觉,他把数学老师布置的作业全部推给yoyo计算。yoyo很头疼,于是请你帮他写一个计算器帮忙计算。现有多个数学表达式,请你写一个计算器算出结果,表达式只包含'+''-''*''/''%''('')'操作,其中表达式中'-'作为减运算符,不会作为负号出现,此外'/'为整除运算符,'%'为取余运算符。表达式保证合法。

输入

输入第一行t,表示共有t行测试用例,接下来t行每一行均为一个合法的数学表达式。保证每个数在[09999]范围内,保证计算过程中不会出现超范围情况。(注:没有空格)

输出

输出计算结果

样例输入

7
0*1
5%6
1-2*(3+4*5%6)+7/8-9*10%11*12
(1+2*3)
1-(100%5)
(3+2*5)/(5)
(11-11)+(33)*64-11

样例输出

0
5
-135
7
1
2
2101

提示

数据很水,不用考虑long long或取余等情况。

题解

逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)(c+d)转换为ab+cd+

如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

例如(a+b)(c+d)转换为ab+cd+ 计算机在计算普通表达式时,要对运算优先级用递归进行判断,对于更为复杂的表达式会使计算机运算效率变低甚至崩溃。而逆波兰表达式只需要进行简单的入栈出栈操作就可以完成任何普通表达式的运算。

普通表达式——>逆波兰表达式

(1)a+b——>a b +

(2)a+(b-c)——>a b c - +

(3)a+(b-c)d——>a b c - d +

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100007;
map<char,int>Pri;//其实可以不必用map,只是为了方便大家理解map而多添加的一步
stack<int>num;
stack<char>Ope;
char str[maxn];
//初始化
void init(){
    Pri['+'] = Pri['-'] = 1;
    Pri['*'] = Pri['/'] = Pri['%'] = Pri['('] = Pri[')'] = 2;
    while(!num.empty())
        num.pop();
    while(!Ope.empty())
        Ope.pop();
}
//基本运算操作
void operation_1(int &a,int &b, char c){
    if(c == '+')
        a += b;
    else if(c == '-')
        a = b-a;
    else if(c == '*')
        a *= b;
    else if(c == '/')
        a = b/a;
    else if(c == '%')
        a = b%a;
}
//遇到+或者)时执行的操作
void operation_2(){
    char ch = Ope.top();
        while(ch != '('&&!Ope.empty()){
            Ope.pop();
            int a = num.top();
            num.pop();
            int b = num.top();
            num.pop();
            operation_1(a,b,ch);
            num.push(a);
            if(!Ope.empty())
                ch = Ope.top();
        }
        if(!Ope.empty()&&Ope.top() == '(')
            Ope.pop();
}
int main(){
    int t;
    cin>>t;getchar();
    while(t--){
        cin.getline(str,maxn);
        stringstream s(str);
        init();
        char tmp;
        while(s >> tmp){
        	//遇到数字字符时,需要判断下一位是否依旧是数字,是的话需要合并
            if(tmp >= '0' && tmp <= '9'){
                int t = 0;
                do{
                    if(Pri[tmp]){
                        break;
                    }
                    t *= 10;
                    t += tmp - '0';
                }while(s >> tmp);
                num.push(t);
            }
            //遇到')'时
            if(tmp == ')'){
                operation_2();
            }
            //遇到'+' ‘-’时
            else if(Pri[tmp]==1){
                if(!Ope.empty()&&Ope.top()!='('){
                    operation_2();
                }
                Ope.push(tmp);
            }
            else if(Pri[tmp]){
                Ope.push(tmp);
            }
        }
        int ans = num.top();
        num.pop();
        while(!num.empty()&&!Ope.empty()){
            operation_1(ans,num.top(),Ope.top());
            Ope.pop();
            num.pop();
        }
        cout << ans << endl;
    }
    return  0;
}

猜你喜欢

转载自blog.csdn.net/qq_40507857/article/details/81142098