这段代码实现了一个基本的算术表达式求值功能,支持加、减、乘运算和括号优先级。通过两个栈来管理操作数和操作符,并逐步解析和计算表达式的值,最终返回计算结果。
代码:
class Solution {
public:
int solve(string s) {
stack<int> val;
stack<char> ops;
for(int i=0; i<=s.length();){
if(s[i]>='0'&&s[i]<='9')
val.push(toInt(s, i));
else if(ops.empty()||ops.top()=='('||s[i]=='(')
ops.push(s[i++]);
else if(s[i]=='*'){
int t1=val.top(),t2=toInt(s, ++i);
val.pop();
val.push(t1*t2);
}
else{
int t2=val.top();
val.pop();
int t1=val.top();
val.pop();
if(ops.top()=='+')
val.push(t1+t2);
else if(ops.top()=='-')
val.push(t1-t2);
else if(ops.top()=='*')
val.push(t1*t2);
ops.pop();
if(s[i]==')'){
ops.pop();
i++;
}
else if(i==s.length())
break;
}
}
return val.top();
}
int toInt(string s,int &i){
int tmp=0;
while(s[i]<='9'&&s[i]>='0')
tmp=tmp*10+s[i++]-'0';
return tmp;
}
};
示例:
输入: "(2*(3-4))*5" 返回值: -10
1. 初始设置
stack<int> val; // 用于存储操作数的栈
stack<char> ops; // 用于存储操作符的栈
初始化两个栈 val
和 ops
分别用于存储操作数和操作符。
2. 遍历字符串 (2*(3-4))*5
通过 for
循环遍历输入字符串 "(2*(3-4))*5"
。我们将逐步分析代码在每个字符时的处理。
Step 1: 处理 '('
-
遇到
(
时,直接将其压入ops
栈。ops.push(s[i++]); // ops 栈现在是 ['(']
Step 2: 处理 '2'
-
遇到数字字符
2
,调用toInt
函数将其转换为整数2
并压入val
栈。val.push(2); // val 栈现在是 [2]
Step 3: 处理 '*'
-
遇到
*
,根据代码逻辑,当前运算符栈顶是(
,所以*
被压入ops
栈。ops.push(''); // ops 栈现在是 ['(', '']
Step 4: 处理 '('
-
遇到
(
,将其压入ops
栈。ops.push('('); // ops 栈现在是 ['(', '*', '(']
Step 5: 处理 '3'
-
遇到数字字符
3
,调用toInt
函数将其转换为整数3
并压入val
栈。val.push(3); // val 栈现在是 [2, 3]
Step 6: 处理 '-'
-
遇到
-
,当前运算符栈顶是(
,所以-
被压入ops
栈。ops.push('-'); // ops 栈现在是 ['(', '*', '(', '-']
Step 7: 处理 '4'
-
遇到数字字符
4
,调用toInt
函数将其转换为整数4
并压入val
栈。val.push(4); // val 栈现在是 [2, 3, 4]
Step 8: 处理 ')'
-
遇到
)
,表示当前括号内的表达式结束。此时需要进行一次运算。-
弹出
val
栈中的两个操作数t1 = 3
和t2 = 4
。 -
弹出
ops
栈中的操作符-
,执行3 - 4 = -1
。 -
将结果
-1
压入val
栈。val.pop(); // val 栈现在是 [2, -1]
ops.pop(); // ops 栈现在是 ['(', '*']
-
-
弹出
ops
栈中的左括号(
。ops.pop(); // ops 栈现在是 ['(']
Step 9: 处理 ')'
-
再次遇到
)
,表示需要继续处理括号外的乘法*
运算。-
弹出
val
栈中的两个操作数t1 = 2
和t2 = -1
。 -
弹出
ops
栈中的操作符*
,执行2 * -1 = -2
。 -
将结果
-2
压入val
栈。val.pop(); // val 栈现在是 [-2]
ops.pop(); // ops 栈现在是 ['(']
-
-
弹出
ops
栈中的左括号(
。ops.pop(); // ops 栈现在是 []
Step 10: 处理 '*'
-
遇到
*
,当前运算符栈为空,直接将*
压入ops
栈。ops.push(''); // ops 栈现在是 ['']
Step 11: 处理 '5'
-
遇到数字字符
5
,调用toInt
函数将其转换为整数5
并压入val
栈。val.push(5); // val 栈现在是 [-2, 5]
Step 12: 结束表达式
-
现在字符串已遍历完毕,需要进行最终的乘法运算。
-
弹出
val
栈中的两个操作数t1 = -2
和t2 = 5
。 -
弹出
ops
栈中的操作符*
,执行-2 * 5 = -10
。 -
将结果
-10
压入val
栈。val.pop(); // val 栈现在是 [-10]
ops.pop(); // ops 栈现在是 []
-
3. 返回结果
-
最后
val
栈顶的值即为最终结果,函数返回-10
。return val.top(); // 返回 -10