详解逆波兰表达式的转换与表达式求值

article/2025/9/19 9:50:33

对于计算一个算式 如 :  3*(5+6)-2

这种算式叫做中缀表达式, 人们看着会比较方便, 如果用计算机直接计算会很麻烦,所以要把中缀表达式变为计算机易于理解的后缀表达式来计算.

后缀表达式又叫逆波兰表达式, 把运算量写在前面, 把运算符写在后面, 并且可以去掉括号

如 a+b 变为 a b +

a*(b+c) 可以变为 a b c + *

 

将普通算式转化为逆波兰表达式的步骤如下:

1. 从左到右扫描算式, 如果是数字, 计算数字的值后直接输出

2. 如果是左括号, 直接加入栈

3. 如果是右括号,查询栈顶是否为左括号, 如果是, 把左括号出栈,

如果不是,输出栈顶的符号, 出栈, 继续第三步,  直到找到左括号

4. 如果是 +, -, *, /, 运算符,比较当前运算符和栈顶运算符的优先级,

如果该运算符的优先级大于栈顶运算符的优先级或者栈为空或者栈顶符号为括号, 把该运算符入栈,

否则, 也就是小于等于的情况, 输出栈顶的符号, 出栈.

 

将算式中的所有元素都处理完后即可得到该算式逆波兰表达式.

C++代码如下:

#include <bits/stdc++.h>
using namespace std;
char str[100][20];
int len=0;   //记录输入的算式长度 
/*
*用于计算运算符的优先级 
*/
int Grade(char ch) 
{if(ch=='*' || ch=='/')return 2;else if(ch=='+' || ch=='-')return 1;else return 0;
}
void Against()
{stack<char>s;//输出原算式 printf("原算式:\n"); for(int i=0 ;i<len; i++) printf("%s ", str[i]);printf("\n");printf("转化成逆波兰表达式:\n"); //转化成逆波兰表达式 for(int i=0; i<len; i++) {//如果是数直接输出这个数 if(str[i][0]>='0' && str[i][0]<='9') printf("%s ", str[i]);//不是数,就为运算符,这是在输入的中缀式合法的情况下计算的 else if(s.empty()) {//当栈为空时,直接把当前运算符入栈 s.push(str[i][0]);}//当运算符为左括号时,无条件入栈 else if(str[i][0]=='(')  s.push('(');else if(str[i][0]==')') {/**当运算符为有括号时, 查看栈顶元素,*当栈顶元素不为左括号,出栈并输出*当栈顶元素为左括号时,出栈 */while(1) {char ch = s.top();if(ch!='(') {s.pop();printf("%c ", ch);}else {s.pop();break;}}}else {/*判断 +, -, *, /, 四种符号*/while(1) {//如果栈为空, 入栈 if(s.empty()) {s.push(str[i][0]);break;}	/**比较当前运算符和栈顶运算符的优先级*如果当前的大于栈顶的,入栈*否则出栈输出并继续比较 */ char ch = s.top();char operater = str[i][0];if(Grade(operater) > Grade(ch)){//((operater == '*' || operater=='/') && (ch=='+' || ch=='-') || ch=='(')//两种if条件都可以判断运算符的优先级 s.push(operater);break;}	else {s.pop();printf("%c ", ch);}}	}}//把剩下栈中的运算符输出 while(!s.empty()){printf("%c ", s.top());s.pop();}
}
int main()
{/**输入时注意每个数和运算符要分开,为了以后比较好判断 */while(scanf("%s", str[len++])!=EOF);len--;Against();
} 

 

以 3*(5+6)-2 为例, 转化成逆波兰表达式为 3 5 6 + * 2 -

那么逆波兰表达式该如何计算?

逆波兰表达式的计算机比较简单了.

给出一个逆波兰表达式, 计算过程如下:

1. 判断是数字还是运算符, 如果是数字, 求出数字的值后入栈.

2. 如果是运算符,从栈中出栈两个数字, 用后出栈的数与前出栈的数根据运算符运算, 再把得到的值入栈.                                         

可能这句话不太好理解, 如过先出栈的为num1, 后出栈的是num2, 运算符为减号时, 新的数 num3 = num2 - num1.

 

C++代码如下

#include <bits/stdc++.h>
using namespace std;
char str[100][20];
int len=0;   //记录输入的算式长度 
int Value_Against()
{stack<double>s;printf("逆波兰表达式: ");for(int i=0; i<len; i++)printf("%s ", str[i]);printf("\n");//遍历每个字符串 for(int i=0; i<len; i++) {//如果为数字,计算出数字,入栈 if(str[i][0] >= '0' && str[i][0] <= '9') {int num=0;for(int j=0; j<strlen(str[i]); j++)num = num*10 + (str[i][j] - '0');s.push(num);}else {/**如果是运算符,从栈中弹出两个数,*根据运算符计算后把新的数入栈 */double num1 = s.top();s.pop();double num2 = s.top();s.pop();double num3;if(str[i][0] == '+')num3 = num2 + num1;else if(str[i][0] == '-')num3 = num2 - num1;else if(str[i][0] == '*')num3 = num2 * num1;else if(str[i][0] == '/')num3 = num2 / num1;s.push(num3);}}//最后栈顶元素即为答案 printf("求值为%.2lf\n", s.top());
}
int main() 
{while(scanf("%s", str[len++])!=EOF);len--;Value_Against();
} 

就以上面已经转化好的逆波兰表达式为例

可以求出 3*(5+6)-2 的值为 31


http://chatgpt.dhexx.cn/article/CJysTCfI.shtml

相关文章

逆波兰表达式(后缀表达式)C++实现

1 何谓逆波兰表达式 逆波兰表达式又称为后缀表达式&#xff0c;是波兰逻辑学家J・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法。 例如&#xff1a; 1 2 3&#xff0c;转换为逆波兰表达式&#xff1a;1 2 3 。 1 2 * 3&#xff0c;转换为逆波兰表达…

将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值。

要求&#xff1a;设计一个算法&#xff0c;将一般算术表达式转化为逆波兰表达式&#xff0c;并求逆波兰表达式的值。 实现思路 获取一个中缀表达式将表达式转换为后缀表达式计算后缀表达式的结果 中缀表达式转换为后缀表达式的几个关键部分 假如不是运算符&#xff0c;则输…

波兰表达式与逆波兰表达式

文章目录 波兰表达式逆波兰表达式波兰表达式计算逆波兰表达式计算总结 常见的算术表达式&#xff0c;称为中缀表达式&#xff0c;例如&#xff1a; 5 ( 6 – 4 / 2 ) * 3波兰表达式 波兰表达式也称为前缀表达式&#xff0c;以上面的例子为例&#xff0c;其波兰表达式为&…

逆波兰表达式

逆波兰表达式在维基百科上的解释&#xff1a;逆波兰表示法&#xff08;Reverse Polish notation&#xff0c;RPN&#xff0c;或逆波兰记法&#xff09;&#xff0c;是一种是由波兰数学家扬武卡谢维奇1920年引入的数学表达式方式&#xff0c;在逆波兰记法中&#xff0c;所有操作…

【数据结构】-------逆波兰表达式(C++)

文章目录 逆波兰表达式讲解正常表达式转换到逆波兰表达式栈操作逆波兰表达式的原理多位数压入栈操作代码例题 逆波兰表达式讲解 逆波兰表达式-----是数据结构的应用&#xff0c;你要单独说讨论它的话没有多大意义&#xff0c;如果我们结合数据结构中的栈来讲解的话&#xff0c…

什么是逆波兰表达式?

文章目录 1. 题目描述2. 解题思路3. 动图演示4. 代码实现 1. 题目描述 2. 解题思路 逆波兰表达式由波兰的逻辑学家卢卡西维兹提出&#xff0c;它的特点是&#xff1a;没有括号&#xff0c;运算符总是放在和它相关的操作数之后。因此&#xff0c;逆波兰表达式也称后缀表达式&am…

微信网页开发中授权headimgurl有的为空

微信网页开发授权&#xff0c;有的用户头像链接为空。 微信开发文档&#xff1a;https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html headimgurl用户头像&#xff0c;最后一个数值代表正方形头像大小&#xff08;有0、46、64、…

微信开发——网页授权

微信开发——网页授权 前期准备前端后端 前期准备 ①微信客户端中访问第三方页面&#xff0c;公众号可以通过网页登陆授权&#xff0c;获取微信用户的基本信息&#xff08;头像、昵称等&#xff09;&#xff0c;实现业务逻辑。一切按照官方文档说明开发。 ②安装微信开发者工具…

微信公众号微信网页开发网页授权/回调自定义参数问题处理方法。

微信公众号页面授权回调自定义参数问题 我们知道微信页面回调接口&#xff0c;获得用户信息后&#xff0c;回调地址&#xff1a; redirect_uri&#xff1a;授权后重定向的回调链接地址&#xff0c; 请使用 urlEncode 对链接进行处理。 授权后跳转回页面&#xff1a; redirec…

微信网页开发--分享接口

流程 关于流程&#xff0c;在上一篇中已经有图介绍: 微信文档 微信JS-SDK说明文档 JSSDK使用步骤 首先确保已经获取了相关权限 步骤一&#xff1a;绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 备注&#xff1a;登录后…

微信网页开发样式库的使用

一、WeUI 是什么 WeUI 是一套同微信原生视觉体验一致的基础样式库&#xff0c;由微信官方设计团队为微信内网页和微信小程序量身设计&#xff0c;令用户的使用感知更加统一。在微信网页或小程序中使用 WeUI&#xff0c;有如下优势&#xff1a; 1. 同微信客户端一致的视觉效果…

微信网页开发(10)--扫一扫功能接口

点此查看 微信公众号/微信网页/微信支付/企业微信/小程序开发合集及源代码下载 本文目录 1. 背景2. 代码3. 测试 1. 背景 我们可以在微信网页调起扫一扫功能&#xff0c;可以识别一维码、二维码的内容&#xff0c;然后根据扫码结果实现我们的业务逻辑。 2. 代码 代码如下&am…

微信公众号开发—通过网页授权实现业务系统登录及用户绑定(微信网页授权自动登录业务系统)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; 微信公众号开发—通过网页授权实现业务系统登录及用户绑定(微信网页授权…

微信网页开发,禁止右上角微信复制分享链接JS

禁止微信右上角分享链接 开发网页时&#xff0c;为了提高网页链接的安全&#xff0c;不想让别人分享链接给别人 一般微信打开网页后&#xff0c;点击右上角是这样的 想要网页不能被复制&#xff0c;不能分享给其他人 效果图&#xff1a; 资源文件下载地址 下载地址 直接贴…

开发微信网页及调试方法

参考资料 Mac中怎么使用Nginx实现80端口转发8080端口 - 大数据 - 亿速云 使用代理映射解决微信页面调试难题 | 梦翼坊 微信开发工具里的域名必须是在微信公众号白名单里的域名,而npm run dev大多是localhost,所以为了方便调试,需要如下步骤 在Charles勾选Proxy-macOS Proxy…

微信网页开发之JS-SDK初使用

最近需要做一个页面&#xff0c;该页面使用微信浏览器打开&#xff0c;功能如下&#xff1a; 1、用户打开链接之后获取到用户的openId&#xff0c;用于支付、获取后台数据等场景 2、自定义分享链接、标题、图标、描述等 3、隐藏微信页面中的某些菜单项列表 阅读本文前需掌握…

微信网页开发--获取微信用户信息

流程 用户扫码或者直接点击链接进入我们的入口页面&#xff1b;进入授权登录页面&#xff0c;用户点击授权登录按钮&#xff1b;微信会自动将我么的网页授权域名后增加参数&#xff1b;根据微信给的code去获取当前登录的微信用户的用户信息。 具体操作过程 1.配置网页授权域名…

微信网页开发(4)--使用JSSDK基础接口

点此查看 微信公众号/微信网页/微信支付/企业微信/小程序开发合集及源代码下载 本文目录 1. JSSDK接口2. 基础接口3. 开发流程3.1 绑定域名3.2 引入JS文件3.3 通过config接口注入权限验证配置3.5 调用基础接口 4. 小结 1. JSSDK接口 微信提供了很多JSSDK接口&#xff0c;包括基…

微信网页开发(8)--地理位置接口

点此查看 微信公众号/微信网页/微信支付/企业微信/小程序开发合集及源代码下载 本文目录 1. 背景2. 代码3. 测试 1. 背景 微信网页提供了获取当前地理位置经纬度&#xff0c;以及通过内置地图查看当前位置的接口。 官方接口说明如下&#xff1a; // 获取位置 wx.getLocation…

微信公众号开发——2、微信网页开发

第一部分、为公众号菜单嵌入网页 一、关键参考文档 微信JS-SDK说明文档 。 二、编辑模式嵌入网页 在公众号平台下&#xff0c;自定义菜单&#xff0c;添加菜单&#xff0c;并选择菜单内容跳转到指定页面地址即可&#xff08;需认证后方可添加页面地址&#xff0c;个人账号暂不…