数据结构与算法--表达式求值

一、表达式求值的概念

算术表达式由操作、运算符组成,在计算机中进行算术表达式的计算是通过堆栈来实现的。通常两个栈就能实现表达式求值。

二、计算机中的表达式求值

1.计算机采用从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,将运算符压入另一个堆栈。

2.其中涉及一个运算符号优先级的问题。如图:

(图片来自百度)

(1) 先计算括号内,后计算括号外;

(2) 在无括号或同层括号内,先乘除运算,后加减运算,即乘除运算的优先级高于加减运算的优先级;

(3) 同一优先级运算,从左向右依次进行。

3.在引入运算符号优先级的概念后。计算机将逐个字符分析表达式,直到全部字符都已分析完。
(1)若当前字符为数字,则判断是否后续字符也为数字,若为数字则进行拼接,直到下一个数字为运算符为止,此时将拼接好的多位数字压入数字栈中。(如果已经是最后一个字符则直接压入栈)
(2)若当前字符为算数运算符,如果运算符栈为空则直接压入栈中,运算符不为空,则对运算符优先级进行判断,如果当前运算符优先级大于等于栈顶运算符则直接压入栈中。如果优先级低于栈顶运算符,则从数字栈中取出两个数据,将当前栈顶运算符弹出进行运算,将结果压入数字栈中,将当前运算符压入运算符栈中。此时数字与运算符都已经压入栈中,此时运算符栈中均为优先级相同的运算符需要进行收尾操作,如果运算符栈不为空,则依次从数字栈中弹出两个数据,与当前栈顶的运算符进行运算。将结果压入数字栈中。最后数字栈中的数字就是所要求解的结果。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <unordered_map>

using namespace std;

stack<int> num;
stack<char> op;

void eval()
{
    auto b = num.top();
    num.pop();
    auto a = num.top();
    num.pop();
    auto c = op.top();
    op.pop();
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a * b;
    else x = a / b;
    num.push(x);
}

int main()
{
    unordered_map<char, int> pr{ {'+', 1}, {'-', 1}, {'*', 2}, {'/', 2} };
    string str;
    cin >> str;
    for (int i = 0; i < str.size(); i++)
    {
        auto c = str[i];
        if (isdigit(c))
        {
            int x = 0, j = i;
            while (j < str.size() && isdigit(str[j]))
                x = x * 10 + str[j++] - '0';
            i = j - 1;
            num.push(x);
        }
        else if (c == '(') op.push(c);
        else if (c == ')')
        {
            while (op.top() != '(') eval();
            op.pop();
        }
        else
        {
            while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
            op.push(c);
        }
    }
    while (op.size()) eval();
    cout << num.top() << endl;
    return 0;
}

运行如下:

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值