表达式求值

这段代码实现了一个基本的算术表达式求值功能,支持加、减、乘运算和括号优先级。通过两个栈来管理操作数和操作符,并逐步解析和计算表达式的值,最终返回计算结果。

代码:

复制代码
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; // 用于存储操作符的栈

初始化两个栈 valops 分别用于存储操作数和操作符。

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 = 3t2 = 4

    • 弹出 ops 栈中的操作符 -,执行 3 - 4 = -1

    • 将结果 -1 压入 val 栈。

      val.pop(); // val 栈现在是 [2, -1]
      ops.pop(); // ops 栈现在是 ['(', '*']

  • 弹出 ops 栈中的左括号 (

    ops.pop(); // ops 栈现在是 ['(']

Step 9: 处理 ')'

  • 再次遇到 ),表示需要继续处理括号外的乘法 * 运算。

    • 弹出 val 栈中的两个操作数 t1 = 2t2 = -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 = -2t2 = 5

    • 弹出 ops 栈中的操作符 *,执行 -2 * 5 = -10

    • 将结果 -10 压入 val 栈。

      val.pop(); // val 栈现在是 [-10]
      ops.pop(); // ops 栈现在是 []

3. 返回结果

  • 最后 val 栈顶的值即为最终结果,函数返回 -10

    return val.top(); // 返回 -10

相关推荐
想跑步的小弱鸡3 小时前
Leetcode hot 100(day 3)
算法·leetcode·职场和发展
xyliiiiiL5 小时前
ZGC初步了解
java·jvm·算法
爱的叹息5 小时前
RedisTemplate 的 6 个可配置序列化器属性对比
算法·哈希算法
独好紫罗兰6 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法
每次的天空6 小时前
Android学习总结之算法篇四(字符串)
android·学习·算法
请来次降维打击!!!7 小时前
优选算法系列(5.位运算)
java·前端·c++·算法
qystca7 小时前
蓝桥云客 刷题统计
算法·模拟
别NULL7 小时前
机试题——统计最少媒体包发送源个数
c++·算法·媒体
weisian1518 小时前
Java常用工具算法-3--加密算法2--非对称加密算法(RSA常用,ECC,DSA)
java·开发语言·算法
程序员黄同学9 小时前
贪心算法,其优缺点是什么?
算法·贪心算法