这里为可带括号的四则运算求值,先转为逆波兰表达式,再解逆波兰表达式的值,解法具有可拓展性
class ReversePolishNotation {public:ReversePolishNotation(string s) {if (!s.empty()) {transferToRePolish(s);computeReversePolish();}}private://计算逆波兰表达式的值,栈的经典应用void computeReversePolish() {stack<float> stk;for (auto s : v) {if (!isOperator(s)) {stk.emplace(stof(s));}else {float y = stk.top();stk.pop();float x = stk.top();stk.pop();float num;if (s == "+") num = x + y;else if (s == "-") num = x - y;else if (s == "*") num = x*y;else num = x / y;stk.emplace(num);}}cout << stk.top() << endl;}//中缀表达式转换为逆波兰表达式,也是栈的经典应用//遍历到完整数字,追加到逆波兰表达式式尾//遍历到左括号入栈,遇到右括号,弹栈直到遇到左括号,把弹出的元素追加到逆波兰表达式式尾//遍历操作符ch,如果它的优先级小于等于栈顶操作符的优先级,则弹栈,把弹出的元素追加到逆波兰表达式式尾,//最后把该操作符ch压栈,维持栈顶优先级最高,维持一个递增栈。//遍历结束时,弹出所有的元素,并依次追加到逆波兰表达式式尾void transferToRePolish(const string& s) {int size = s.size();stack<char> stk;int i = 0;while (i < size) {if ((s[i] >= '0'&&s[i] <= '9') || s[i] == '.') {int j = i;while (s[i] >= '0'&&s[i] <= '9')i++;if (j - 1 >= 0 && (s[j - 1] == '-' || s[j - 1] == '+') && j - 2 >= 0 && s[j - 2] == '(') {stk.pop();v.emplace_back(s.substr(j - 1, i - j + 1));}elsev.emplace_back(s.substr(j, i - j));}else if (s[i] == '(') {stk.push(s[i++]);}else if (s[i] == ')') {while (stk.top() != '(') {v.emplace_back(to_string(stk.top()));stk.pop();}stk.pop();i++;}else {while (!stk.empty() && priority(s[i]) <= priority(stk.top())) {v.emplace_back(to_string(stk.top()));stk.pop();}stk.emplace(s[i]);i++;}}while (!stk.empty()) {v.emplace_back(to_string(stk.top()));stk.pop();}}int priority(char ch) {switch (ch) {case '(': return 0;case '-':case '+': return 1;case '*':case '/': return 2;default: return -1;}}bool isOperator(const string& s) {return s.size() == 1 && string("+-*/").find(s[0]) != string::npos;}private:vector<string> v;};
