蓝桥杯 算法训练 表达式计算

题目

问题描述

  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。

输入格式

  输入一行,包含一个表达式。

输出格式

  输出这个表达式的值。

样例输入

1-2+3*(4-5)

样例输出

-4

数据规模和约定

  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。


想法

使用后缀表达式计算即可。在这里有几个需要注意的地方。第一个是注意从数据栈中弹出两个操作数时,先弹出的是后操作数,这一点在进行减法和除法运算时需要注意。第二个是对后缀表达式的理解,先弹出的符号表示实际运算的优先级高,所以当读取到一个符号时,应当弹出优先级高于或者等于当前运算符的符号进行运算,因为平级运算也有有先后的。第三个是在读入表达式的时候,读到数字不能只读一位,而是而是应当考虑数字位数更多的情况。第四个是在使用C++的stack时,在进行条件判断时应当把OP.empty()放在前面,不然如果stack为空,尝试访问栈顶元素会出错。

附:后缀表达式计算

规则:左至右遍历中缀表达式中每个数字和符号:

1.若是数字直接输出,即成为后缀表达式的一部分

2.若是符号:

(1)若是),则将栈中元素弹出并输出,直到遇到“(”, “(”弹出但不输出;

(2)若是(+*等符号,则从栈中弹出并输出优先级高于或等于当前的符号,直到遇到一个优先级低的符号或者左括号然后将当前符号压入栈中。

优先级+-最低,*/次之,“(”最高

3.遍历结束,将栈中所有元素依次弹出,直到栈为空。


实现 

#include<iostream>
#include<cctype>
#include<stack>

using namespace std;

int compute(int a,int b,char op);

int main(void)
{
    char ch;
    stack<int>NUM;
    stack<char>OP;
    while((ch=getchar())!=EOF){
        if(isdigit(ch)){
            int num=ch-'0';
            while((ch=getchar())!=EOF){
                if(isdigit(ch)) num=num*10+ch-'0';
                else{
                    ungetc(ch,stdin);
                    break;
                }
            }
            NUM.push(num);
        }
        else{
            if(ch=='(') OP.push(ch);
            else if(ch=='*'||ch=='/'){
                while(!OP.empty()&&(OP.top()=='*'||OP.top()=='/')){
                    int b=NUM.top();
                    NUM.pop();
                    int a=NUM.top();
                    NUM.pop();
                    int op=OP.top();
                    OP.pop();
                    NUM.push(compute(a,b,op));
                }
                OP.push(ch);
            }
            else if(ch=='+'||ch=='-'){
                while(!OP.empty()&&(OP.top()=='*'||OP.top()=='/'||OP.top()=='+'||OP.top()=='-')){
                    int b=NUM.top();
                    NUM.pop();
                    int a=NUM.top();
                    NUM.pop();
                    int op=OP.top();
                    OP.pop();
                    NUM.push(compute(a,b,op));
                }
                OP.push(ch);
            }
            else if(ch==')'){
                while(!OP.empty()&&OP.top()!='('){
                    int b=NUM.top();
                    NUM.pop();
                    int a=NUM.top();
                    NUM.pop();
                    int op=OP.top();
                    OP.pop();
                    NUM.push(compute(a,b,op));
                }
                OP.pop();
            }
        }
    }
    while(!OP.empty()){
        int b=NUM.top();
        NUM.pop();
        int a=NUM.top();
        NUM.pop();
        int op=OP.top();
        OP.pop();
        NUM.push(compute(a,b,op));
    }
    cout<<NUM.top();
}

int compute(int a,int b,char op)
{
    int ans=0;
    switch(op){
        case '+':
            ans=a+b;
            break;
        case '-':
            ans=a-b;
            break;
        case '*':
            ans=a*b;
            break;
        case '/':
            ans=a/b;
            break;
    }
    return ans;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值