乘除优先于加减计算,直接从左到右计算所有乘除运算,并将这些乘除运算的结果压栈。而运算符只是作为数字的符号一同压栈,使用pre_sign记录当前数字的符号
若碰到数字,则继续解析数字,直到碰到下一个非数字符号。碰到下一个符号后,根据pre_sign将计算结果压栈,并更新pre_sign和num,继续解析后面的数字
若碰到符号,则根据pre_sign将计算结果压栈,并更新pre_sign和num,继续解析后面的数字
字符串解析完成后,直接将stack中的数字相加即可
class Solution {
public:
int calculate(string s) {
char pre_sign = '+';
stack<int> st;
int num = 0;
int n = s.size();
for(int i = 0; i < n; i++){
if(isdigit(s[i])){
num = num * 10 + (s[i] - '0');
}
if((!isdigit(s[i]) && s[i] != ' ') || i == n - 1){
int tmp;
switch(pre_sign){
case '+':
st.push(num);
break;
case '-':
st.push(0 - num);
break;
case '*':
tmp = st.top();
st.pop();
st.push(tmp * num);
break;
case '/':
tmp = st.top();
st.pop();
st.push(tmp / num);
break;
}
pre_sign = s[i];
num = 0;
}
}
int ans = 0;
while(!st.empty()){
ans += st.top();
st.pop();
}
return ans;
}
};
和上一题唯一不同的地方就是本题需要考虑括号,如果碰到左括号,则找到与其对应的右括号,截取出括号内的表达式,再次调用solve计算即可,用返回值更新num
class Solution {
public:
int solve(string s) {
stack<int> st;
char pre_sign = '+';
int n = s.size();
int num = 0;
for (int i = 0; i < n; i++) {
if (isdigit(s[i])) {
num = num * 10 + s[i] - '0';
}
if (s[i] == '(') {
int cnt = 1;
int j = i + 1;
while (cnt > 0) {
if (s[j] == '(') cnt++;
if (s[j] == ')') cnt--;
j++;
}
num = solve(s.substr(i + 1, j - i - 2)); // 截取出排除括号后,需要计算的部分
i = j - 1; // i直接跳到j - 1的位置,中间括号内的部分不用再解析,回到for循环后会++
}
if (s[i] == '+' || s[i] == '-' || s[i] == '*' || i == n - 1) {
// 碰到运算符或最后一个符号,则根据pre_sign将数字num压栈
switch (pre_sign) {
case '+':
st.push(num);
break;
case '-':
st.push(0 - num);
break;
case '*':
int res = st.top() * num;
st.pop();
st.push(res);
break;
}
pre_sign = s[i];
num = 0;
}
}
int ans = 0;
while (!st.empty()) {
ans += st.top();
st.pop();
}
return ans;
}
};