文章目录

  • 1. C++中缀表达式转后缀表达式
  • 2. C++中缀表达式转前缀表达式
  • 3. C++后缀表达式求值
  • 4. C++前缀表达式求值

1. C++中缀表达式转后缀表达式

输入中缀表达式样例:
2+48+(88+1)/3

输出后缀表达式样例:
248*+88*1+3/+

对于中缀表达式转换为后缀表达式,我们需要用以下步骤来解决这个问题:

  1. 初始化一个栈:运算符栈st
  2. 从左往右开始扫描中缀表达式
    • 遇到数字,直接输出
    • 遇到运算符:
      • 若为 ‘(’ 直接入栈
      • 若为 ‘)’ 将符号栈中的元素依次出栈并输出,直到 ‘(’, ‘(’ 只出栈,不输出
      • 若为其他符号,将符号栈中的元素依次出栈并将其输出,直到遇到比当前符号优先级更低的符号或者 ‘(’。
//首先定义优先级
#include <iostream>
#include <string>
#include <stack>using namespace std;int priority(const char ch)
{// */优先级相同最大int priority = 0;if (ch == '*' || ch == '/')priority = 2;else if (ch == '+' || ch == '-')priority = 1;else if (ch == '(')priority = 0;else//其他字符优先级错误priority = -1;return priority;
}string turnPostfix(string &str)
{stack<char> st;string ret; //保存中缀转后缀的结果for (int i = 0; i < str.size(); i++){// cout << str[i] << endl;//如果这个字符没有优先级,说明这个字符不是操作符if (priority(str[i]) == -1 && str[i] != ')'){//字符直接输出ret.push_back(str[i]);}else{if (st.empty()){st.push(str[i]);}else{//如果str[i]==)将栈输出,直到(if (str[i] == ')'){while (st.top() != '('){ret.push_back(st.top());st.pop();}//将(弹出栈st.pop();}else{//如果是(直接入栈if (str[i] == '('){st.push(str[i]);}else{//将优先级大于这个操作符的字符出栈输出//cout << "INFO:" << st.top() << endl;while (!st.empty() && priority(st.top()) >= priority(str[i])){ret.push_back(st.top());st.pop();}//将这个操作符号入栈st.push(str[i]);}}}}}//将栈剩下的元素全部出栈while (!st.empty()){ret.push_back(st.top());st.pop();}return ret;//调用string的拷贝构造函数返回
}int main()
{//string input = "2+4*8+(8*8+1)/3";string input = "a*(b+c)-d";cout << turnPostfix(input) << endl;return 0;
}

2. C++中缀表达式转前缀表达式

整体思路正好于后缀相反

输入中缀表达式:(a+b) * (c+d)

输出前缀表达式为: * ,+,a,b,+,c,d。

  1. 初始化一个运算符栈st

  2. 从右至左扫描中缀表达式,从右边第一个字符开始判断。

    • 遇到数字直接输出
    • 如果是运算符,则比较优先级。如果当前运算符的优先级大于等于栈顶运算符的优先级则将运算符直接入栈;否则将栈顶运算符 出栈并输出,直到当前运算符的优先级大于等于栈顶运算符的优先级,再将这个运算符入栈(当栈顶是括号时,直接入栈)
      • 如果是括号,则根据括号的方向进行处理。如果是右括号,则直接入栈;否则,遇左括号前将所有的运算符全部出栈并输出,并将左右括号删除
        -最后将字符串逆转就是前缀表达式
//首先定义优先级
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>using namespace std;int priority(const char ch)
{// */优先级相同最大int priority = 0;if (ch == '*' || ch == '/')priority = 2;else if (ch == '+' || ch == '-')priority = 1;else if (ch == ')')priority = 0;else//其他字符优先级错误priority = -1;return priority;
}string turnPrefix(const string &str)
{string ret;stack<char> st;for (int i = str.length() - 1; i >= 0; i--){// cout << str[i] << " " << endl;if (priority(str[i]) == -1 && str[i] != '('){//数字,直接输出到ret上即可ret.push_back(str[i]);}else{if (str[i] == '('){//弹出栈,直到遇到)while (st.top() != ')'){ret.push_back(st.top());st.pop();}//将')'弹出栈st.pop();}else{if (st.empty()){st.push(str[i]);}else{if (str[i] == ')'){//右括号直接入栈st.push(str[i]);}else{//栈优先级大的出栈while (!st.empty() && priority(st.top()) > priority(str[i])){ret.push_back(st.top());st.pop();}//将这个操作符入栈st.push(str[i]);}}}}}while (!st.empty()){ret.push_back(st.top());st.pop();}std::reverse(ret.begin(), ret.end());return ret;
}int main()
{string input = "1+((2+3)*4)-5";cout << turnPrefix(input) << endl;return 0;
}

3. C++后缀表达式求值

  1. 准备一个数字栈。从左到右扫描后缀表达式
  2. 如果是数字,放入数字栈。
  3. 如果是符号,从数字栈中弹出两个数字,第一个取出的数字为右运算数,第二个为左运算数,进行运算。然后将结果放进数字栈中。
  4. 如此反复,直到读完整个表达式后,留在数字栈中的那个数字就是最终结果。
#include <iostream>
#include <string>
#include <stack>
#include <map>
#include <functional>using namespace std;//传入后缀表达式
int PostfixToNumber(const string &str)
{std::map<char, std::function<int(int, int)>> opMap ={{'+', [](int x, int y){ return x + y; }},{'-', [](int x, int y){ return x - y; }},{'*', [](int x, int y){ return x * y; }},{'/', [](int x, int y){ return x / y; }},};stack<int> st;for (int i = 0; i < str.length(); i++){if (str[i] >= '0' && str[i] <= '9'){st.push(str[i] - '0');}else{int right = st.top();st.pop();int left = st.top();st.pop();//实际上就是switch case 不同的运算符执行不同的运算,我这里使用C++11包装器st.push(opMap[str[i]](left,right));}}return st.top();
}int main()
{//"2+4*8+(8*8+1)/3"cout<<PostfixToNumber("248*+88*1+3/+")<<endl;
}

4. C++前缀表达式求值

  1. 创建一个数字栈

  2. 从右至左扫描表达式,从右边第一个字符开始判断如果当前字符(或字符串)为数字或变量,则直接压入数字栈内;如果是运算符,则弹出两个数字运算;如此反复,直到读完整个表达式;

需要注意:

 后缀表达式右值为第一个栈顶元素,左值为第二个栈顶元素前缀左值为第一个栈顶元素,右值为第二个栈顶元素
#include <iostream>
#include <string>
#include <stack>
#include <map>
#include <functional>using namespace std;//传入前缀表达式
int PrefixToNumber(const string &str)
{std::map<char, std::function<int(int, int)>> opMap ={{'+', [](int x, int y){ return x + y; }},{'-', [](int x, int y){ return x - y; }},{'*', [](int x, int y){ return x * y; }},{'/', [](int x, int y){ return x / y; }},};stack<int> st;for (int i = str.length() - 1; i >= 0; i--){if (str[i] >= '0' && str[i] <= '9'){st.push(str[i] - '0');}else{int left = st.top();st.pop();int right = st.top();st.pop();st.push(opMap[str[i]](left,right));}}return st.top();
}int main()
{//1+((2+3)*4)-5 cout<<PrefixToNumber("-+1*+2345")<<endl;return 0;
}

Github地址(2023考研数据结构实操,大题代码)

参考博客:

栈的应用之前、中、后缀表达式(C++)

前缀表达式和后缀表达式 - C++代码

【PTA】后缀表达式 (中缀表达式转化为后缀表达式)

数据结构 - 拓展突破(C++实现中缀表达式转前缀表达式,中缀表达式转后缀表达式,前缀表达式求值,中缀表达式求值)相关推荐

  1. 数据结构-拓展突破-特殊矩阵(对称矩阵,三角矩阵,三对角矩阵,稀疏矩阵)的压缩存储)

    文章目录 1. 对称矩阵 2. 三角矩阵 3. 三对角矩阵 4. 稀疏矩阵 1. 对称矩阵 对称矩阵的定义: 若n阶方阵中任意一个元素a,都有a(i,j)=a(j,i)则该矩阵为对称矩阵 也就是说对称 ...

  2. 中缀、后缀、前缀表达式

    一.简介 对于1+((2*3)-4)/2 的数学表达式怎么求值? 分析: 数学表达式求值有优先级,不能简单的从左往右依次计算, 需要从优先级高的开始计算 中缀表达式是一种通用的算术或逻辑公式表示方法, ...

  3. 由中缀表达式求后缀、前缀表达式cpp代码

    前缀中缀后缀定义 一个表达式树.前序遍历得到前缀,中序遍历得到中缀,后序遍历得到后缀.单纯的中缀表达式会引起计算歧义,所以为了计算一般要完全括号化:或者将中缀转换为前缀或者后缀.注意:前缀和后缀没有歧 ...

  4. 使用脚本编写 Vim 编辑器,第 1 部分: 变量、值和表达式

    优秀的文本编辑器 有这样一则老笑话:如果 Emacs 拥有一款优良的文本编辑器,那么它将是一个优秀的操作系统,相反,如果 vi 拥有一个不错的操作系统,那么它将是一款非常出色的文本编辑器.这个笑话反映 ...

  5. 设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值

    栈的设计与使用 实验内容 设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达的值 解题思路 (1)一般算术表达(中缀表达),如#3×(4+2)/2-5#,#为表达式界定符,逆波兰表达式( ...

  6. python函数拟合不规则曲线_python 对任意数据和曲线进行拟合并求出函数表达式的三种解决方案...

    第一种是进行多项式拟合,数学上可以证明,任意函数都可以表示为多项式形式.具体示例如下. ###拟合年龄 import numpy as np import matplotlib.pyplot as p ...

  7. java lambda表达式_恕我直言你可能真的不会java第1篇:lambda表达式会用了么?

    本文配套教学视频:B站观看地址 在本号之前写过的一些文章中,笔者使用了lambda表达式语法,一些读者反映说代码看不懂.本以为java 13都已经出了,java 8中最重要特性lambda表达式大家应 ...

  8. 表达式如何获取复选框的值_Nuke表达式 Expression节点讲解

    nuke中的表达式节点对于大多数人来说有点神秘,但它非常强大.通常它通过简单的if / else语句修补数据,但在这里我们将从最基本的原则,到一些长期被遗忘的高中数学做一些简单的技巧,最后把它们融合在 ...

  9. c++求n的几次方_14.八年级数学:若a+b+c=1,怎么求 a+b+c的值?分式培优拓展

    欢迎您来到方老师数学课堂,请点击上方蓝色字体,关注方老师数学课堂.所有的视频内容,全部免费,请大家放心关注,放心订阅. 八年级数学:若a²+b²+c²=1,怎么求 a+b+c的值?分式培优拓展.这道题 ...

最新文章

  1. 2021年第十六届全国大学生智能汽车竞赛赛道铺设规范
  2. docker基础维护命令
  3. parameter乱码提交的问题
  4. 洛谷P5357 - 【模板】AC自动机(二次加强版)(AC自动机+fail树)
  5. 你每隔多久使用计算机上网查找资料英文,牛津英语8B Unit3导学案
  6. es集群节点数和分片数关系_ES数据插入和查询流程是怎么样的?
  7. python是什么专业学的-当我们学Python时,我们学什么?
  8. My Job Exceptation
  9. PPT素材模板哪个网站资源内容比较丰富?
  10. 曼哈顿距离与切比雪夫距离的亲密♂关系。
  11. Azure微软云(部署一台虚拟机云服务器)
  12. configure文件的生成
  13. 关于小梅哥ADC128S022驱动设计的思考
  14. Windows Azure Platform (三)云计算的特点
  15. python 请假审批系统_基于工作流的请假审批系统设计与实现
  16. 同程旅游网开放平台SDK开发完成
  17. Robotic Process Automation 机器人流程自动化(2)
  18. 与卿共赴鸿蒙什么意思,表达情人相思的诗句
  19. 让1元钱变成两百万 三种赚100万的策略
  20. 魔兽世界首页静态界面

热门文章

  1. pytorch实现ResNet50模型(小白学习,详细讲解)
  2. 忘记虚拟机主机管理员登录密码
  3. git 回退到某个版本,并推送到远程
  4. MySQL表锁、行锁、排它锁和共享锁
  5. java 中常用的类(笔记 十六)
  6. windows桌面应用程序UI自动化工具(转载)
  7. 儿时的动画,你看过那些?-混沌时期
  8. Thinkphp3.2 查询物流接口对接(快递鸟为例)
  9. HC32 CAN通信
  10. ULAM /区块链未来将颠覆的9个行业