中缀表达式求值(栈的应用)

这篇具有很好参考价值的文章主要介绍了中缀表达式求值(栈的应用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、题目来源

AcWing算法基础课-3302.表达式求值

二、题目描述

给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

注意:

  • 数据保证给定的表达式合法。
  • 题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-1+2,(2+2)*(-(1+1)+2) 之类表达式均不会出现。
  • 题目保证表达式中所有数字均为正整数。
  • 题目保证表达式在中间计算过程以及结果中,均不超过 \(2 ^ {31} - 1\)
  • 题目中的整除是指向 \(0\) 取整,也就是说对于大于 \(0\) 的结果向下取整,例如 \(5/3=1\),对于小于 \(0\) 的结果向上取整,例如 \(5/(1−4)=−1\)
  • C++和Java中的整除默认是向零取整;Python中的整除//默认向下取整,因此Python的eval()函数中的整除也是向下取整,在本题中不能直接使用。

输入格式

共一行,为给定表达式。

输出格式

共一行,为表达式的结果。

数据范围

表达式的长度不超过 \(10^5\)

输入样例:

(2+2)*(1+1) 

输出样例:

8 

三、算法思路

本题是中缀表达式求值问题,主要为栈的应用。

思路如下:

  • 首先,设置两个栈,一个为操作符栈,一个为数字栈。
  • 然后,遍历整个序列:
    • 遇到 '(' ,直接 \(push\)
    • 遇到数字,直接 \(push\)
    • 遇到操作符
      • 如果是 '+'、‘-’,那么都可以算
        • \(while\) 栈不空 且 栈顶不是'('
          • 操作
      • 如果是 '*'、'/',那么加减不能先算,只能算乘除
        • \(while\) 栈不空 且 栈顶是 '*'、'/'
          • 操作
      • 最后 \(push\)
    • 遇到 ')'
      • \(while\) 栈顶不是 '('
        • 操作
      • 将 '(' 弹出
  • 处理 操作符栈中 剩余的操作符
  • 数字栈的栈顶为最终答案

注意事项:文章来源地址https://www.toymoban.com/news/detail-747292.html

  • 遇到数字要 \(push\),但是数字可能不是个位数,显然有可能是多位数(但不会是负数),所以需要处理一下。
  • 可以将判断是否是数字、加减、乘除、操作这些抽象成函数,这样代码好写一些。
  • 一定要注意,加减的运算级比乘除低,所以遇到加减可以算之前的乘除,而遇到乘除不能先算之前的加减,例如 \(2+3*5\),如果搞错了就会得出 \(25\),读者自行思考。
  • 遍历完之后别忘了将剩余的操作符都要处理掉。

四、源代码

#include <iostream>

using namespace std;

const int N = 100010;

char op[N];
int num[N];
int opt, numt;

void init()
{
    opt = 0;
    numt = 0;
}

bool isDigit(char c)
{
    if (c >= '0' && c <= '9')   return true;
    return false;
}

bool isAddOrSub(char c)
{
    if (c == '+' || c == '-')   return true;
    return false;
}

bool isMulOrDiv(char c)
{
    if (c == '*' || c == '/')   return true;
    return false;
}

void func()
{
    char c = op[-- opt];
    int num1 = num[-- numt], num2 = num[-- numt];
    
    int res = 0;
    if (c == '+')   res = num2 + num1;
    else if (c == '-')  res = num2 - num1;
    else if (c == '*')  res = num2 * num1;
    else    res = num2 / num1;
    
    num[numt ++ ] = res;
}

int main()
{
    string s;
    cin >> s;
    
    init();
    
    for (int i = 0; i < s.size(); ++i)
    {
        if (s[i] == '(')    op[opt ++ ] = s[i];
        else if (isDigit(s[i]))
        {
            int res = 0, j = i;
            while (j < s.size() && isDigit(s[j]))
                res = res * 10 + s[j ++ ] - '0';
                
            num[numt ++ ] = res;
            
            i = j - 1;
        }
        else if (isAddOrSub(s[i]) || isMulOrDiv(s[i]))
        {
            if (isAddOrSub(s[i]))
                while (opt != 0 && op[opt - 1] != '(')
                    func();
            else
                while (opt != 0 && isMulOrDiv(op[opt - 1]))
                    func();
        
            op[opt ++ ] = s[i];
        }
        else
        {
            while (op[opt - 1] != '(')  func();
            opt -- ;
        }
    }
    
    while (opt != 0)    func();
    
    cout << num[numt - 1] << endl;
    
    return 0;
}

到了这里,关于中缀表达式求值(栈的应用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java LeetCode篇-深入了解关于栈的经典解法(栈实现:中缀表达式转后缀)

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍     文章目录         1.0 中缀表达式转后缀说明         1.1 实现中缀表达式转后缀思路         2.0 逆波兰表达式求值         2.1 实现逆波兰表达式求值思路         3.0 有效的括号         3.1 实现有

    2024年02月04日
    浏览(60)
  • 栈的OJ题(逆波兰表达式求值+括号匹配+出入栈顺序匹配+最小栈)

    平时使用是算式是中缀表达式 逆波兰表达式是一种后缀表达式,算符写在后面。 优点: 1.去掉括号后表达式无歧义 2.适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中 3.中缀转后缀:加上括号,将对应的运算符放在括号外 1.题

    2024年02月08日
    浏览(49)
  • 4.2 实现基于栈的表达式求值计算器(难度4/10)

    本作业主要考察:解释器模式的实现思想/栈结构在表达式求值方面的绝对优势 C++数据结构与算法夯实基础作业列表 通过栈的应用,理解特定领域设计的关键作用,给大家眼前一亮的感觉。深刻理解计算机语言和人类语言完美结合的杰作。是作业中的上等作品,是数据结构与

    2024年02月10日
    浏览(35)
  • 北京林业大学数据结构实验二 基于栈的算术表达式求值算法

    参见课本P75 例3.3

    2024年02月06日
    浏览(48)
  • 【数据结构】12 堆栈应用:表达式求值

    有一个常量表达式的中缀表达式为:5 + 6 / 2 - 3 * 4,其后缀形式表示为: 5 6 2 / + 3 4 × -。后缀表达式的特点是运算符位于两个预算数之后。其前缀表达式为: - + 5 / 6 2 × 3 4。 后缀表达式相比于中缀表达式的求值要容易很多。 从左到右扫描该表达式: (1)遇见运算数5 6 2时不

    2024年02月20日
    浏览(59)
  • 【数据结构】【栈(stack)应用】四则运算表达式求值(带括号)

            先理解原理,再看代码,注意标红字体很重要!结尾附完整测试代码,C语言实现! 更新留言:         本来是侧重演示栈结构的使用,后面评论区发现很多朋友对这个四则运算比较感兴趣,特此做了更新,新增了对负数的运算支持。         若您也有新的想法

    2024年02月08日
    浏览(46)
  • 【数据结构】【栈(stack)应用】四则运算表达式求值(支持括号、负数)

            先理解原理,再看代码,注意标红字体很重要!结尾附完整测试代码,C语言实现! 更新留言:         本来是侧重演示栈结构的使用,后面评论区发现很多朋友对这个四则运算比较感兴趣,特此做了更新,新增了对负数的运算支持。         若您也有新的想法

    2024年02月05日
    浏览(49)
  • 中缀表达式转后缀表达式

      一种不需要括号的后缀表达法,也把它称为 逆波兰 表示,是波兰逻辑学家卢卡西维奇(Lukasiewicz)发明的一种表示表达式的方法。   中缀表达式指的是“9+(3-1)×3+8÷2”,这种就是我们通常见到的书写算式顺序,要计算中缀表达式则首先要将字符串转换为后缀表达式,即

    2023年04月08日
    浏览(47)
  • 算术表达式:前缀、中缀表、后缀表达式相互转换

    概念: 三者的区别在于运算符相对于操作数的位置有所不同   前缀表达式 前缀表达式是一种没有括号的算术表达式,与中缀表达式不同的是,其将运算符写在前面,操作数写在后面。   中缀表达式  中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于

    2024年02月05日
    浏览(93)
  • 【数据结构与算法】【12】前缀表达式、中缀表达式、后缀表达式

    什么是前缀表达式、中缀表达式、后缀表达式 前缀表达式、中缀表达式、后缀表达式,是通过树来存储和计算表达式的三种不同方式 以如下公式为例 ( a + ( b − c ) ) ∗ d ( a+(b-c) )*d ( a + ( b − c ) ) ∗ d 通过树来存储该公式,可以表示为 那么问题就来了,树只是一种抽象的数据

    2024年02月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包