其他分享
首页 > 其他分享> > 中缀转逆波兰然后计算表达式的值

中缀转逆波兰然后计算表达式的值

作者:互联网

中缀转逆波兰

用一个栈装操作符

1、遇到数字就输出
2、遇到操作符,如果栈空直接放入,如果左括号直接放入,如果是右括号,输出并弹出栈顶直到遇到左括号,再把左括号弹出(不用输出),
如果是四则运算符,如果当前比栈顶优先级高,直接放入,否则输出并弹出所有优先级大于等于当前运算符的,再放入当前运算符。
最后将栈里剩下的元素输出弹出

逆波兰求值

每次弹两个,算一下,放回去,最后结果就是栈剩下的最后一个元素

#include<bits/stdc++.h>

using namespace std;


class Solution {
public:
    int f(char c) { // 运算符的优先级
        if(c == '*' || c == '/') {
            return 2;
        }
        else if(c == '+' || c == '-') {
            return 1;
        }
        return -1;
    }
    int calculate(string s) {
        int n = s.size();

        string suffix = "";
        stack<char> op;
        for(int i = 0; i < n; i++) {
            if(s[i] == ' ') {
                continue;
            }

            if('0' <= s[i] && s[i] <= '9') {
                suffix.push_back(s[i]);
            }
            
            else { // 四个运算符
                suffix.push_back(' ');
                if(op.empty()) {
                    op.push(s[i]);
                }
                else{
                    if(s[i] == '(') {
                        op.push(s[i]);
                    }
                    else if(s[i] == ')') {
                        while(op.top() != '(') {
                            suffix.push_back(op.top());
                            op.pop();
                        }
                        op.pop();
                    }
                    else {
                        // 如果当前优先级更高,直接加入栈中
                        if(f(s[i]) > f(op.top())) {
                            op.push(s[i]);
                        }
                        else {
                            //弹出,直到栈顶优先级低于当前的优先级,再加入当前的运算符
                            while(!op.empty() && f(op.top()) >= f(s[i])) {
                                suffix.push_back(op.top());
                                op.pop();
                            }
                            op.push(s[i]);
                        }
                    }
                    
                }
                
            }
        }

        suffix.push_back(' ');
        while(!op.empty()) {
            suffix.push_back(op.top());
            op.pop();
        }
        cout<<suffix<<endl;
        return calcSuffix(suffix);
    }

    int calcSuffix(string suffix) {
        int n = suffix.size();
        int num = 0; // 临时记录数据

        stack<int> s; // 计算表达式的栈
        bool flag = false;
        
        for(int i = 0; i < n; i++) {
            if(suffix[i] == ' ') {
                cout<<"num="<<num<<endl;
                if(flag) {
                    s.push(num);
                }
                num = 0;
                flag = false;
            }
            else if('0' <= suffix[i] && suffix[i] <= '9') {
                num =  num * 10 + (suffix[i]-'0');
                flag = true;
            }
            else if(suffix[i] == '+' || suffix[i] == '-' || suffix[i] == '*' || suffix[i] == '/'){
                int x = s.top(); s.pop();
                int y = s.top(); s.pop();
                if(suffix[i] == '+') {
                    s.push(y+x);
                }
                else if(suffix[i] == '-') {
                    s.push(y-x);
                }
                else if(suffix[i] == '*') {
                    s.push(y*x);
                }
                else {
                    s.push(y/x);
                }
            }
        }
        return s.top();
    }
};

int main() {
    Solution s;
    int res = s.calculate("1 + 2  + 3*4 + (5/6) -7");
    cout<<"the answer is "<< res<<endl;
    return 0;
}

标签:转逆,优先级,中缀,int,运算符,suffix,push,表达式,op
来源: https://www.cnblogs.com/consolexinhun/p/15787019.html