LeetCode 227. 基本计算器 II
使用传统栈后缀表达式+弹栈计算,爆时间爆内存,垃圾解法;
mapmp; vector bs; void init() { mp['+'] = 0; mp['-'] = 0; mp['*'] = 1; mp['/'] = 1; } void back_string(string s) { stack sign; int i = 0; while(i = '0' && s[i] <= '9') { string ss = ""; while (s[i] >= '0' && s[i] <= '9') { ss += s[i]; i++; } bs.push_back(ss); } else if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'){ if (sign.empty()) { sign.push(s[i]); } else { if (mp[s[i]] > mp[sign.top()]) { sign.push(s[i]); } else { while (!sign.empty() && mp[s[i]] <= mp[sign.top()]) { string str = ""; str += sign.top(); bs.push_back(str); sign.pop(); } sign.push(s[i]); } } i++; } else { i++; } } while (!sign.empty()) { string str = ""; str += sign.top(); bs.push_back(str); sign.pop(); } } int calculate(string s) { init(); stack st; back_string(s); int a, b; int ret = 0; for (int i = 0; i < bs.size(); i++) { if (bs[i] == "+") { a = st.top(); st.pop(); b = st.top(); st.pop(); st.push(a + b); } else if (bs[i] == "-") { a = st.top(); st.pop(); b = st.top(); st.pop(); st.push(b - a); } else if (bs[i] == "*") { a = st.top(); st.pop(); b = st.top(); st.pop(); st.push(a * b); } else if (bs[i] == "/") { a = st.top(); st.pop(); b = st.top(); st.pop(); st.push(b / a); } else { int cnt = 0; for (int j = 0; j < bs[i].size(); j++) { cnt = (bs[i][j] - '0') + cnt * 10; } st.push(cnt); } } return st.top(); }
最快的写法应该是采用之前简单加减运算之上,增加乘除优先级即可;
遇到加减元素,标记正负号之后按照数字入栈;
如果遇到乘除符号,则两位操作数只可能是现在的遍历得数目和栈顶元素,所以弹栈计算之后进行压栈;
但是值得注意的是,每次判断都是根据presign进行的,所以每次计算落后于实际遍历操作;
最后只需要对栈内元素进行加和计算即可;
class Solution {
public:
int calculate(string s) {
vector stk;
char preSign = '+';
int num = 0;
int n = s.length();
for (int i = 0; i < n; ++i) {
if (isdigit(s[i])) {
num = num * 10 + int(s[i] - '0');
}
if (!isdigit(s[i]) && s[i] != ' ' || i == n - 1) {
switch (preSign) {
case '+':
stk.push_back(num);
break;
case '-':
stk.push_back(-num);
break;
case '*':
stk.back() *= num;
break;
default:
stk.back() /= num;
}
preSign = s[i];
num = 0;
}
}
return accumulate(stk.begin(), stk.end(), 0);
}
};