中缀表达式转后缀表达式C++实现

前言: 中缀表达式转后缀表达式也是近年来找工作笔试、面试、考研机试,算法竞赛中的考点,所以学会它也是很有必要的,因为这种问题的代码比较模板化,建议读者直接背诵模板,但是不能死记硬背,而是在理解算法思路的基础上背诵此代码。

读者可以先阅读这篇博客 —> 博客传送门

因为表达式求值中的代码中隐含了一步,即将中缀表达式转换成后缀表达式,因此只需要将表达式求值的代码稍作修改即可得到中缀表达式转后缀表达式的代码。

题目

给定一个中缀表达式,其中运算符仅包含 + , − , ∗ , / +,-,*,/ +,,,/(加 减 乘 整除),可能包含括号,请你将中缀表达式转换成后缀表达式。

输入

( 2 ∗ 1 + 6 ) ∗ ( 5 − 3 ) / 4 (2*1+6)*(5-3)/4 (21+6)(53)/4

输出

2 2 2 1 1 1 ∗ * 6 6 6 + + + 5 5 5 3 3 3 − - ∗ * 4 4 4 / / /

实现思路

  1. 若碰到操作数,直接输出在后缀表达式中;
  2. 若碰到左括号,直接将左括号压入操作符栈中;
  3. 若碰到右括号,弹出操作符栈中的操作符直到碰到左括号为止,弹出操作符将操作符输出在后缀表达式中;
  4. 若碰到操作符,弹出操作符栈中优先级 大于或者等于 大于或者等于 大于或者等于该操作符的元素(若碰到到左括号或者栈为空应该停止),弹出操作符将操作符输出在后缀表达式中;
  5. 若扫描完字符串后,运算符栈不为空,弹出操作符输出在后缀表达式中直到栈为空,算法结束;

手动模拟

步骤1
在这里插入图片描述
步骤2
在这里插入图片描述
步骤3
在这里插入图片描述
步骤4
在这里插入图片描述
步骤5
在这里插入图片描述
步骤6
在这里插入图片描述
步骤7
在这里插入图片描述
步骤8
在这里插入图片描述
步骤9
在这里插入图片描述
步骤10
在这里插入图片描述
步骤11
在这里插入图片描述
步骤12
在这里插入图片描述
步骤13
在这里插入图片描述
步骤14
在这里插入图片描述
步骤15
在这里插入图片描述
步骤16
在这里插入图片描述

代码(附详细注释)

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

//定义操作符栈和操作数栈
stack<char> op;

//弹出操作符,输出操作符
void eval(){
    char c = op.top();
    op.pop();
    cout << c << " ";
}

int main(){
    //读入表达式字符串
    string s;
    cin >> s;
    
    //定义四个操作符的优先级; 加减的优先级比乘除低,这里定义加减是1,乘除是2
    map<char, int> mp = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
    
    //从左到右扫描一遍字符串
    for(int i = 0; i < s.size(); i++){
        //四种情况分别对应该字符是数字,左括号,右括号,操作符
        if(isdigit(s[i])){
            //operand存储操作数,因为操作数在字符串里面可能有连续几位
            int j = i, operand = 0;
            //这段代码不要害怕,实际上是将字符串"1234"转换成数字1234的代码
            while(j < s.size() && isdigit(s[j])){
                operand = operand * 10 + s[j] - '0';
                j++;
            }
            cout << operand << " "; //遇到操作数直接输出在表达式
            i = j - 1; //for循环里面会执行i++,所以这里j需要减去1
        }else if(s[i] == '('){
            op.push(s[i]); //左括号则压栈
        }else if(s[i] == ')'){
            //右括号则一直匹配,直到碰到左括号位置
            while(op.top() != '(') eval();
            op.pop();
        }else{
            //若栈不为空且没有碰到左括号且栈顶元素的优先级大于等于该操作符的优先级
            while(op.size() && op.top() != '(' && mp[op.top()] >= mp[s[i]])
                eval();
            op.push(s[i]); //将操作符压入栈中
        }
    }
    //操作到运算符栈空为止
    while(op.size()) eval();
    return 0;
}

注意

  1. 实现中缀表达式转后缀表达式,只需要将表达式求值的代码中有关操作数栈的代码删除,改成遇见操作数直接输出操作数,操作运算符直接输出即可;
  2. 只要理解了表达式求值的代码,中缀表达式转后缀表达式代码稍作修改,直接背诵
  3. 其他的注意点请见这篇博客 —>博客传送门

如果觉得对你有所帮助的话,麻烦你点赞,收藏,关注我,后期还会更新博客

  • 29
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米兰的小码匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值