C++ 符号栈(加强版)

描述

给定一个字符串描述的算术表达式,计算出结果值。

输入字符串长度不超过 100 ,合法的字符包括 ”+, -, *, /, (, )” , ”0-9” 。

注意事项

数字可能会带有符号前缀,需要注意。

可以使用string::stoi()将字符串转成数字,包括前缀-,+

具体做法

用栈来解决括号,我们用一个栈记录刚刚的计算结果,每次都与栈顶元素计算,然后加入栈顶,用另一个栈记录包括括号在内的所有运算符,根据运算优先级来计算第一个栈中的内容。

因为不用考虑括号的合法性,我们可以在栈中添加括号。遍历的时候遇到左括号就将其加入栈中,遇到右括号依次弹出运算符栈和数字栈中的内容进行计算,直到遇到左括号为止,就相当于计算了一个子问题,运算结果依旧存在栈中,不影响后续的计算。

遇到数字要区分正负号和加减号,可以用一个flag标记每轮是否出现过了数字了,数字之前的为正负号,数字之后的为加减号。

#include <iostream>
#include <stack>
using namespace std;

void compute(stack<int> &st1, stack<char> &st2)
{ //根据栈顶运算符弹出栈顶两个元素进行运算
    int b = st1.top();
    st1.pop();
    int a = st1.top();
    st1.pop();
    char op = st2.top(); //栈顶运算符
    st2.pop();
    if (op == '+')
        a = a + b; //加
    else if (op == '-')
        a = a - b; //减
    else if (op == '*')
        a = a * b; //乘
    else if (op == '/')
        a = a / b; //除
    st1.push(a);
}

bool priority(char m, char n)
{                 //比较运算符优先级
    if (m == '(') //括号优先级最高
        return false;
    else if ((m == '+' || m == '-') && (n == '*' || n == '/')) //加减法小于乘除法
        return false;
    return true;
}

int main()
{
    string s;
    while (cin >> s)
    {
        stack<int> st1;  //记录运算数字
        stack<char> st2; //记录运算符
        st2.push('(');   //整个运算式添加括号
        s += ')';
        bool flag = false;
        for (int i = 0; i < s.length(); i++)
        {
            if (s[i] == '(') //如果是左括号都在运算符栈加入(
                st2.push('(');
            else if (s[i] == ')')
            { //遇到右括号
                while (st2.top() != '(')
                { //弹出开始计算直到遇到左括号
                    compute(st1, st2);
                }
                st2.pop(); //弹出左括号
            }
            else if (flag)
            { //运算符
                while (priority(st2.top(), s[i]))
                {                      //比较运算优先级
                    compute(st1, st2); //可以直接计算
                }
                st2.push(s[i]); //需要将现阶段加入栈中等待运算
                flag = false;
            }
            else
            {                                   //数字
                int j = i;                      //记录起始
                if (s[j] == '-' || s[j] == '+') //正负号
                    i++;
                while (isdigit(s[i]))
                {
                    i++;
                }
                string temp = s.substr(j, i - j);
                st1.push(stoi(temp)); //截取数字部分,转数字
                i--;
                flag = true; //数字结束,下一次flag为true就是运算符了
            }
        }
        cout << st1.top() << endl; //输出
    }

    return 0;
}

参考:题解 | #表达式求值#_牛客博客

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值