这段代码实现了一个基本的算术表达式求值功能,支持加、减、乘运算和括号优先级。通过两个栈来管理操作数和操作符,并逐步解析和计算表达式的值,最终返回计算结果。
代码:
class Solution {
public:
int solve(string s) {
stack val;
stack 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 val; // 用于存储操作数的栈
stack 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