表达式求值

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

代码:

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

相关推荐
半盏茶香10 分钟前
扬帆数据结构算法之雅舟航程,漫步C++幽谷——LeetCode刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
数据结构·c++·算法
CodeJourney.29 分钟前
小型分布式发电项目优化设计方案
算法
带多刺的玫瑰1 小时前
Leecode刷题C语言之从栈中取出K个硬币的最大面积和
数据结构·算法·图论
Cando学算法1 小时前
Codeforces Round 1000 (Div. 2)(前三题)
数据结构·c++·算法
薯条不要番茄酱1 小时前
【动态规划】落花人独立,微雨燕双飞 - 8. 01背包问题
算法·动态规划
小林熬夜学编程1 小时前
【Python】第三弹---编程基础进阶:掌握输入输出与运算符的全面指南
开发语言·python·算法
字节高级特工1 小时前
【优选算法】5----有效三角形个数
c++·算法
小孟Java攻城狮7 小时前
leetcode-不同路径问题
算法·leetcode·职场和发展
查理零世7 小时前
算法竞赛之差分进阶——等差数列差分 python
python·算法·差分
小猿_0010 小时前
C语言程序设计十大排序—插入排序
c语言·算法·排序算法