https://leetcode.com/problems/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.Example 1:
Input: "3+2*2" Output: 7Example 2:
Input: " 3/2 " Output: 1Example 3:
Input: " 3+5 / 2 " Output: 5Note:
- You may assume that the given expression is always valid.
- Do not use the
eval
built-in library function.
字符串形式的算术表达式处理,原本想的是先组织成一棵二叉树,然后利用二叉树的后序遍历这样传统的方法来实现,但实在是有些繁琐,看了别人的博客之后才发现原来有这么直观的解法
利用栈:
本质上相当于两次遍历,第一次先处理*/,第二次处理+-,实现了优先级的区分
op用于记录当前数字的前一个符号。可以将一个数字看作是由两个符号相夹的,前一个符号代表它的运算,后一个符号代表它可以执行运算(同时后一个符号也是后一个数字的前一个符号)
class Solution {
public:
int calculate(string s) {
s.push_back('+');
stack<int> S;
int cur_num = 0;
char op = '+';
for(int i = 0; i < s.size(); ++i){
if(s[i] == ' ') continue;
else if(s[i] >= '0' && s[i] <= '9'){
cur_num = cur_num*10+(s[i]-'0');
}else{
if(op == '+'){
S.push(cur_num);
cur_num = 0;
}else if(op == '-'){
S.push(-cur_num);
cur_num = 0;
}else if(op == '*'){
S.top() *= cur_num;
cur_num = 0;
}else{
S.top() /= cur_num;
cur_num = 0;
}
op = s[i];
}
}
int result = 0;
while(!S.empty()){
result += S.top();
S.pop();
}
return result;
}
};
话说stack竟然不支持迭代器,令我感到很惊讶
不依赖栈:
仔细考虑上述方法可以发现,其中的栈所起到的功能并不大,只是作为一个记录而已,也没有出栈操作,活跃的永远只是顶部元素,最后的操作也只是单纯的累和,因此我们可以直接将栈拆成两个整型变量来实现,分别用于记录不活跃元素的累和和活跃元素的值。
class Solution {
public:
int calculate(string s) {
s.push_back('+');
int cur_num = 0;
int cur_result = 0;
int result = 0;
char op = '+';
for(int i = 0; i < s.size(); ++i){
if(s[i] == ' ') continue;
else if(s[i] >= '0' && s[i] <= '9') cur_num = cur_num*10 + (s[i]-'0');
else{
if(op == '+'){
cur_result += cur_num;
}else if(op == '-'){
cur_result -= cur_num;
}else if(op == '*'){
cur_result *= cur_num;
}else if(op == '/'){
cur_result /= cur_num;
}
cur_num = 0;
op = s[i];
if(op == '+' || op == '-'){
result += cur_result;
cur_result = 0;
}
}
}
return result;
}
};