表达式求值

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

代码:

复制代码
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

相关推荐
偷吃的耗子8 分钟前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
dazzle1 小时前
机器学习算法原理与实践-入门(三):使用数学方法实现KNN
人工智能·算法·机器学习
那个村的李富贵1 小时前
智能炼金术:CANN加速的新材料AI设计系统
人工智能·算法·aigc·cann
张张努力变强1 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
万岳科技系统开发1 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
张登杰踩1 小时前
MCR ALS 多元曲线分辨算法详解
算法
YuTaoShao2 小时前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法一)排序+滑动窗口
算法·leetcode·排序算法
波波0072 小时前
每日一题:.NET 的 GC是如何分代工作的?
算法·.net·gc
风暴之零2 小时前
变点检测算法PELT
算法
深鱼~2 小时前
视觉算法性能翻倍:ops-cv经典算子的昇腾适配指南
算法·cann