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.
题意&解题思路:
就是简单的算术加减乘除,以字符串形式给出式子,让我们返回结果。
因为没有括号啥的,故优先级的话 “*”“/”> “+”“-“,然后同一优先级先算前面再算后面,我第一想法是直接按照每个运算符进行字符串的递归拆分处理,结果Memory Limit Exceeded了(后知后觉,消耗的内存的确很大),代码如下:
class Solution {
public:
bool isNum(string s){
int len = s.length();
int i = 0;
while(i < len)
if(s[i] == ' ' || (s[i] >= '0' && s[i] <= '9'))i++;
else return 0;
return 1;
}
int cal(string s){
if(isNum(s))return atoi(s.c_str());
int len = s.length();
int ind = len - 1;
while(ind >= 0){
if(s[ind] == '+' || s[ind] == '-')break;
ind--;
}
if(ind != len){
if(s[ind] == '+'){
return cal(s.substr(0, ind)) + cal(s.substr(ind + 1));
}
if(s[ind] == '-'){
return cal(s.substr(0, ind)) - cal(s.substr(ind + 1));
}
}
ind = len - 1;
while(ind >= 0){
if(s[ind] == '*' || s[ind] == '/')break;
ind--;
}
if(s[ind] == '*'){
return cal(s.substr(0, ind)) * cal(s.substr(ind + 1));
}
if(s[ind] == '/'){
return cal(s.substr(0, ind)) / cal(s.substr(ind + 1));
}
return 0;
}
int calculate(string s) {
return cal(s);
}
};
不能用递归,那把递归改为用栈处理,将乘除法优先处理,另外“-”其实可以看为当前数乘以-1,同当乘法处理,估最后处理完存进栈里的数直接全部加起来即可,AC代码如下(15ms):
class Solution {
public:
int calculate(string s) {
char c;
stack<int>st;
while(!st.empty())st.pop();
int len = s.length();
st.push(atoi(s.c_str()));//直接把第一个数放进堆里
int ind = 0;
while(ind < len && (s[ind] == ' ' || s[ind] >='0' && s[ind] <= '9'))ind++;
while(ind < len){
c = s[ind++];
int cur = ind;
while(cur < len && (s[cur] == ' ' ||s[cur] >='0' && s[cur] <= '9'))cur++;
int b = atoi(s.substr(ind, cur-ind).c_str());
if(c == '*' || c == '/'){
int a = st.top();
st.pop();
if(c == '*')st.push(a*b);
else st.push(a/b);
}
else {
if(c == '-')st.push(-b);
else {
st.push(b);
}
}
ind = cur;
}
int ans = 0;
while(!st.empty()){
ans += st.top();
st.pop();
}
return ans;
}
};
下次记得要考虑内存问题(第一次用Markdown,感觉不错,下次多试下特性)。