题解 | #表达式求值#

表达式求值

http://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d

用中缀表达式直接求值,要关注两个点,一个是')',还有一个是数字和符号交替出现,这个交替出现可以用一个布尔变量来表示,我们可以思考发现数字后面要么是符号要么是')',遇到反括号时应该计算出里面的值,还要记得弹出两个括号,而且可以确定的是反括号后面一定是符号(')'或加减乘除)。说的有点乱看代码解释

#include <algorithm>
#include <stack>

using namespace std;

bool priority(const char &a,const char &b){
    if(a=='(') return false;//这里要a>b,才会是true,才会弹出栈进行计算,false
    //都会压进符号栈可以看到像这种'()'也会把反括号压进符号栈。
    if(((a=='+')||(a=='-'))&&((b=='*')||(b=='/')))
        return false;
    
    return true;
    
}

void compute(stack<int> &si,stack<char> &sc){
    int a = si.top();
    si.pop();
    int b = si.top();
    si.pop();
    char op = sc.top();
    sc.pop();
    switch(op){
        case '+':a=b+a;break;
        case '-':a=b-a;break;
        case '*':a=b*a;break;
        case '/':a=b/a;break;
    }
    si.push(a);//计算结果压入数字栈
    
}

int main() {
    string str;
    while(getline(cin,str)){
        stack<int> si;
        stack<char> sc;
        str = "("+str+")";//先给表达式加个括号,因为下面要和第一个进行比较才进行
        //计算
        int n =str.size();
        bool punct =false;
        for(int i =0;i<n;i++){
            if(str[i]=='('){
                sc.push(str[i]);//遇到括号压进去
            }
            /*else if(str[i]==')'){
                while(priority(sc.top(),str[i])){
                    compute(si,sc);
                }
                sc.pop();
            }这里最开始没把它统一到下面那个判断条件*/
            else if(punct){
                while(priority(sc.top(),str[i])){//如果没有加开头的'('那么现在
                //符号栈是空的,这里会运行错误。这里是大于才是真,才会运算。
                    compute(si,sc);
                }
                
                sc.push(str[i]);
                punct = false;
                if(str[i]==')'){如果遇到压的符号是')'应该弹出两个符号,且下一个还
                //是符号
                    sc.pop();
                    sc.pop();
                    punct = true;
                }
            }
            else{
                int j = i;
                if(str[j]=='+'||str[j]=='-') j++;
                while(isdigit(str[j])){
                    j++;
                }
                string temp = str.substr(i,j-i);
                si.push(stoi(temp));
                i=j-1;//注意外层i还会+1,所以这里-1
                punct = true;//数字完了肯定是符号
            }
            
            
        }//for
        cout<<si.top()<<endl;//最后的数字栈剩个结果,符号栈都为空。
    }
}

其实还可以将中缀表达式转化为后缀表达式,这样就完全不用考虑括号的问题了,更模块化一点

全部评论

相关推荐

点赞 评论 收藏
转发
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务