[LeetCode]104. Basic Calculator II基本计算器
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +
, -
, *
, /
operators and empty spaces . The integer division should truncate toward zero.
You may assume that the given expression is always valid.
Some examples:
"3+2*2" = 7 " 3/2 " = 1 " 3+5 / 2 " = 5
Note: Do not use the eval
built-in library function.
本题与基本计算器I不同的一点是表达式不包含括号,取而代之的是包含有乘除运算。
解法1:先遍历一遍表达式去除无效的空格。然后从头至尾遍历表达式,遇到数字和加减号分别进操作数或操作符栈,遇到乘除号则在操作数栈中取出左操作数,同时从表达式中读出右操作数,计算好结果后入操作数栈。一遍完成后将乘除运算计算完成。根据加减运算的从左至右规律,先将操作数和操作符栈中的元素全部搬运到新的操作数和操作符栈,然后不断从新的操作符栈取操作符,从新的操作数栈取两个操作数,进行加减运算,直至没有操作符,操作数栈顶即为结果。
class Solution { public: int calculate(string s) { stack<char> opc; stack<int> opn; int k = 0; for (int i = 0; i < s.size(); ++i) { if (!isspace(s[i])) s[k++] = s[i]; } s.resize(k); for (int i = 0; i < k; ++i) { if (isdigit(s[i])) { int d = s[i] - '0'; while (i < k && isdigit(s[++i])) d = d * 10 + s[i] - '0'; --i; opn.push(d); } else if (s[i] == '+' || s[i] == '-') opc.push(s[i]); else if (s[i] == '*' || s[i] == '/') { char dom = s[i]; int num1 = opn.top(); opn.pop(); int num2 = (int)(s[++i] - '0'); while (i < k && isdigit(s[++i])) num2 = num2 * 10 + s[i] - '0'; --i; if (dom == '*') opn.push(num1 * num2); else opn.push(num1 / num2); } } stack<char> c; stack<int> n; while (!opc.empty()) { c.push(opc.top()); opc.pop(); } while (!opn.empty()) { n.push(opn.top()); opn.pop(); } while (!c.empty()) { int num1 = n.top(); n.pop(); int num2 = n.top(); n.pop(); char aoa = c.top(); c.pop(); if (aoa == '+') n.push(num1 + num2); else n.push(num1 - num2); } return n.top(); } };
解法2:解法1的一个繁琐之处在于为了从左至右计算加减运算需将两个栈倒过来,可以想办法将这个过程省去。每次遇到第二个操作符,只要不是乘除号,则可以将前面一部分表达式按从左至右顺序计算好。
class Solution { public: int calculate(string s) { stack<char> opc; stack<int> opn; int k = 0; for (int i = 0; i < s.size(); ++i) { if (!isspace(s[i])) s[k++] = s[i]; } s.resize(k); for (int i = 0; i < k; ++i) { if (isdigit(s[i])) { int d = s[i] - '0'; while (isdigit(s[++i])) d = d * 10 + s[i] - '0'; --i; opn.push(d); } else if (s[i] == '+' || s[i] == '-') { if (!opc.empty()) { char dom = opc.top(); opc.pop(); int num2 = opn.top(); opn.pop(); int num1 = opn.top(); opn.pop(); if (dom == '+') opn.push(num1 + num2); else opn.push(num1 - num2); } opc.push(s[i]); } else if (s[i] == '*' || s[i] == '/') { char dom = s[i]; int num1 = opn.top(); opn.pop(); int num2 = (int)(s[++i] - '0'); while (isdigit(s[++i])) num2 = num2 * 10 + s[i] - '0'; --i; if (dom == '*') opn.push(num1 * num2); else opn.push(num1 / num2); } } if (!opc.empty()) { char dom = opc.top(); opc.pop(); int num2 = opn.top(); opn.pop(); int num1 = opn.top(); opn.pop(); if (dom == '+') opn.push(num1 + num2); else opn.push(num1 - num2); } return opn.top(); } };
解法3:将中缀表达式转换为前缀或者后缀表达式再进行计算。见基本计算器I。