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

article/2025/9/19 10:29:40

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

实现思路

  1. 获取一个中缀表达式
  2. 将表达式转换为后缀表达式
  3. 计算后缀表达式的结果

中缀表达式转换为后缀表达式的几个关键部分

假如不是运算符,则输出,否则进行下面步骤

  1. 假如遇到空栈或者‘(’时,直接入栈,并继续,因为第一个遇到的肯定是'#',所以直接入栈。
  2. 假如遇到'#',则说明表达式结束了,但得在前一点的后面进行判断。
  3. 假如遇到')',则进行出栈,知道遇到'(',并弹出,但不记录,因为我们不要括号的
  4. 优先级比较:
  • 假如优先级大于栈顶,则入栈
  • 小于或等于栈顶时,一直出栈,直到当前运算符优先级大于栈顶,则把当前运算符进栈。

计算后缀表达式

前一步已经将表达式存放在新的数组里面了,并且为了方便识别,在适当的位置都加了空格,方便识别。

由于需要进行计算,且要把char的数转换成一个整数,所以这里简单的利用一个整型数组,并且模拟栈的实现方式,基本思想如下:

  1. 对获取到后缀表达式进行扫描
  2. 如果为数字,则继续扫描直到遇到空格,并把数入栈。
  3. 假如为运算符,则进相应的运算,从栈中取出离栈顶最近的两个数,进行计算,并且把结果写在离栈顶较远的那个位置,并且把当前栈顶的数据清零。
  4. 最后获取到的结果会存放在数组的0位置。

结语

由于这个实验是我在学数据结构时的一个实验,刚学习编程,语言也比较混乱,如有错误的地方,欢迎指出。以下为代码部分:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*  (1)设计一个算法,将一般算术表达式转化为逆波兰表达式,并求逆波兰表达式的值。例如 #30*(40+20)/2-50#  #为两个界限符
*/
const int StackSize = 30;
char result[30];//接收转换结果,并添加空格
char num;//用来result数组的计数//定义一个栈结构体
typedef struct Stack
{char data[StackSize];int top;
}StackType;//出栈处理,输入:栈结构体
char Pop(StackType *p)
{char x;if(p->top == -1) {printf("under flow\n");exit(0);}x = p->data[p->top--];return x;
}
//入栈处理
void Push(StackType *p, char dat)
{if(p->top == StackSize -1){printf("over flow\n");exit(0);}p->data[++p->top] = dat;
}//为空时返回1,不为空则返回0
bool Emtry(StackType *p)
{if(p->top == -1)return 1;return 0;
} 
//获取栈顶的数据
char GetTop(StackType *p)
{if(p->top != -1)return p->data[p->top];return 0;
}//判断是运算符还是运算对象bool isNumber(char op){switch(op){ 	case ' ':case '(':case ')':case '+':    	case '-':    	case '*':    	case '/':case '#':		return 0;    default :       return 1;	 }}
//获取运算符的优先级,1为最高,且统计优先级int priority(char ch){int value= 10; switch(ch){case '(':case ')':	value = 4;	break;//当遇到左括号时,所有的符号都会进行入栈处理,直到遇到右括号,或者内部运算输出case '*':	value = 2;	break;case '/':	value = 2;	break;case '+':	value = 3;  break;case '-':	value = 3;	break;case '#':	value = 5;	break;default:  break;}return value;}/*
函数名:Nifix2Postfix	
输  入:数组
返  回:无
功  能:将中缀表达式转换成后缀表达式并输出
*/
void Nifix2Postfix(char arr[])
{StackType* pStack = new StackType;pStack->top = -1;int i = 0;char ch;for(i=0;arr[i] != '\0';i++){if(isNumber(arr[i])){result[num++] = arr[i];}//不是对象时,即为运算符else{//首先判断是否为空,如果为空,则入栈if(Emtry(pStack) || arr[i] == '('){Push(pStack, arr[i]);continue;}if(arr[i] == '#')//结束符号break;if(arr[i] == ')')//出栈直到遇到({result[num++] = ' ';while((ch = Pop(pStack)) != '(' )//开始出栈,出到'('{result[num++] = ch;result[num++] = ' ';}continue;}result[num++] = ' ';//优先级比较ch = priority(GetTop(pStack)) - priority(arr[i]);//获取优先级比较后的结果,但ch>0时,运算符优先级大于栈顶,=0相等,<0小于//优先级大于栈顶if(ch > 0){//优先级大的入栈Push(pStack, arr[i]);}//优先级小于或等于栈顶else if(ch <= 0){//应该是出栈一个,然后判断优先级,假如不为空栈,继续判断优先级,然后将arr[i]入栈while( priority(arr[i]) >= priority(GetTop(pStack)))//此运算符优先级小于等于栈顶时,一直输出{
//					printf("%c",ch = Pop(pStack));result[num++] = Pop(pStack);
//					printf(" ");result[num++] = ' ';}Push(pStack, arr[i]);							}}}while(GetTop(pStack) != '#'){result[num++] = ' ';result[num++] = Pop(pStack);}for(i=0;i<num;i++)printf("%c",result[i]);
}/*
函数功能:计算后缀表达式的值
输入:一个后缀表达式
输出:结果
*/
int Calculate(char arr[])
{int i, cal[10],top=-1;memset(cal,0,sizeof(cal));for(i=0;i<num;i++){if(isNumber(arr[i]))//判断是否是操作符,返回1不是,进来的只能是数字{//模拟入栈top++;while(arr[i] != ' ')//获取一个整数,并入栈{cal[top] = cal[top]*10 + arr[i++]-48;}}else{switch(arr[i]){//模拟出栈case '+':	cal[top-1] = cal[top-1] + cal[top]; cal[top--] = 0; break;case '-':	cal[top-1] = cal[top-1] - cal[top]; cal[top--] = 0; break;case '*':	cal[top-1] = cal[top-1] * cal[top]; cal[top--] = 0; break;case '/':	cal[top-1] = cal[top-1] / cal[top]; cal[top--] = 0; break;default: break;}}}return cal[0];
}int main(void)
{char  express[] = "#30*(40+20)/2-50#";//	gets(express);printf("中缀表达式:");printf("%s\n", express);printf("后缀表达式:");Nifix2Postfix(express);printf("\n");printf("运算结果为:%d\n", Calculate(result));return 0;
}

运行结果:


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

相关文章

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

文章目录 波兰表达式逆波兰表达式波兰表达式计算逆波兰表达式计算总结 常见的算术表达式&#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;个人账号暂不…

微信网页开发配置整理

真是人越大记忆越差&#xff0c;断断续续做了几个微信小程序和微信h5项目&#xff0c;然鹅小程序的开发流程有些都忘了&#xff0c;最近刚做完一个微信h5网页开发的项目&#xff0c;所以赶紧记录下开发中需要注意的点&#xff0c;给自己往后回顾&#xff0c;同时也给第一次接入…

微信网页开发调试的一些方法

1. 微信开发者工具调试 微信开发者工具下载 不过多介绍, 下载安装, 就能开始小程序开发和公众号网页开发. 2. 微信内自带调试 微信内打开网页 http://debugx5.qq.com (仅支持Android微信) 打开下面两项&#xff0c;就可以调试了 3. 使用vConsole插件 1. 下载vConsole插件…