解析字符串中的四则运算(c++)

前几天刷LeetCode时,刷到了LeetCode---224. Basic Calculator和LeetCode---227. Basic Calculator II这两题,都是解析字符串中的四则表达式。题目分别如下:

题目意思很明确,输入的是字符串形式的四则运算,要求输出其四则运算的结果。记得曾经在《大话数据结构》那一本书上见到过使用后缀表达式来求解这类问题。所幸就动手实现一遍。这里可能有两个概念需要解释一下,中缀表达式:就是我们平时正常书写的表达式,运算符位于操作数的中间,例如:9 + 3 * 2,可以看出,运算符 + 与 * 都位于其操作数的中间。后缀表达式就是将运算符提取出来,放到操作数的后面,如中缀表达式 9 + 3 对应的后缀表达式为 9 3 +。当中缀表达式中含有(),+,-,*,/等运算符时怎么由中缀表达式转化为后缀表达式,这里不想过多的讨论了。大家可以参考《大话数据结构》4.9节---栈的应用---四则运算表达式求值( P104页)。下面直接看AC的代码,可以同时解决这两道题:

class Solution {
public:
    int calculate(string s) {
        //求后缀表达式
        string postOrder;
        stack<char> symbol;
        map<char,int> priority = {
            {'(',0},
            {'+',1},
            {'-',1},
            {'*',2},
            {'/',2},
        };
        for(int i = 0;i < (int)s.length(); ++i) {
            if(s[i] == ' ') {
                continue ;
            } else if(isdigit(s[i])) {
                postOrder += s[i];
                while(i < s.length() - 1 && isdigit(s[i + 1])) {
                    postOrder += s[++i];
                }
            } else if(symbol.empty() || s[i] == '(' || (priority[s[i]] > priority[symbol.top()] && s[i] != ')')) {
                symbol.push(s[i]);
            } else if(s[i] == ')') {
                while(!symbol.empty() && symbol.top() != '(') {
                    postOrder += symbol.top();
                    symbol.pop();
                    postOrder += " ";
                }
                symbol.pop();
            } else {
                while(!symbol.empty() && priority[s[i]] <= priority[symbol.top()]) {
                    postOrder += symbol.top();
                    symbol.pop();
                    postOrder += " ";
                }
                symbol.push(s[i]);
            }
            if(!postOrder.empty() && postOrder.back() != ' ') {
                postOrder += " ";
            }
        }
        while(!symbol.empty()) {
            postOrder += symbol.top();
            symbol.pop();
            postOrder += " ";
        }
        //利用后缀表达式来求值
        istringstream iss(postOrder);
        stack<double> st;
        int num = 0;
        char c = '\0';
        while(iss.peek() != EOF) {
            if(isdigit(iss.peek())) {
                iss >> num;
                st.push(num);
                iss.ignore();
            } else {
                int num1 = st.top(); st.pop();
                int num2 = st.top(); st.pop();
                iss >> c;
                switch(c) {
                    case '+' : st.push(num2 + num1); break;
                    case '-' : st.push(num2 - num1); break;
                    case '*' : st.push(num2 * num1); break;
                    case '/' : st.push(double(num2) / double(num1)); break;
                }
                iss.ignore();
            }
        }
        return st.top();
    }
};

猜你喜欢

转载自blog.csdn.net/qq_22158743/article/details/85321640