[数据结构]从中序表达式到逆序表达式(逆波兰式)(四则运算表达式求值)

C++实现中缀表达式转后缀表达式并求值 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。例如:(3 + 4) × 5 - 6 就是中缀表 阅读详情

将运算对象写在前面,而把运算符号写在后面。用这种表示法表示的表达式也称做后缀式。逆波兰式的特点在于运算对象顺序不变,运算符号位置反映运算顺序。采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。(逆波兰式不需要使用括号)

本份代码出自:http://wenku.baidu.com/view/23a5b73031126edb6f1a10aa.html

本份代码需要两个栈。一个是符号栈,一个是数字栈。

输入中序表达式如9+(3-1)*3+10/2#


计算过程


#include<stdio.h>
#include<math.h>
#define max 100
char ex[max];        /*存储后序表达式*/

/*函数功能:将中序表达式转化为后序表达式*/
void trans() {
	char str[max];   /*表达式字符串*/
	char stack[max]; /*运算符栈*/
	char ch;         /*当前字符*/
	int sum, i, j, t, top = 0; /*sum用来统计字符串的长度*/
							   /*t是数字栈栈顶指针*/
							   /*top是数字栈栈顶指针*/
	printf("*****************************************\n");
	printf("*输入一个求值的表达式,以#结束。*\n");
	printf("******************************************\n");
	printf("算数表达式:");

	i = 0;
	/*这个循环语句,获取一个用户输入的合法的表达式*/
	do {
		i++;
		scanf("%c", &str[i]);
	} while (str[i] != '#' && i != max);

	sum = i;
	t = 1;
	i = 1;
	ch = str[i];
	i++;
	//while循环,当前的字符不是#
	while (ch != '#') {
		//将该字符与运算符栈顶的运算符的优先关系相比较。
		//如果该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
		//括号的运算优先级高。
		switch (ch) {
		case '(':            /*判定为左括号,入符号栈*/
			top++;           /*栈顶指针+1*/
			stack[top] = ch;
			break;

		case ')': /*判定为右括号*/
			while (stack[top] != '(') {
				ex[t] = stack[top];/*把符号栈的栈顶元素压入另一个栈中*/
				top--;             /*符号栈的栈顶指针-1*/
				t++;               /*数字栈的栈顶指针+1*/
			}
			top--;
			break;
		case '+': /*判定为加减号*/
		case '-':
			while (top != 0 && stack[top] != '(') {
				ex[t] = stack[top];/*把符号栈的栈顶元素压入数字栈中*/
				top--;             /*符号栈的栈顶指针-1*/
				t++;               /*数字栈的栈顶指针+1*/
			}
			top++;
			stack[top] = ch;       /*不执行那个while循环的话,直接压入符号栈*/
			break;
		case '*': /*判定为乘除号*/
		case '/':
			while (stack[top] == '*' || stack[top] == '/') {
				ex[t] = stack[top];/*把符号栈的栈顶元素压入数字栈中*/
				top--;             /*符号栈的栈顶指针-1*/
				t++;               /*数字栈的栈顶指针+1*/
			}
			top++;
			stack[top] = ch;
			break;
		case ' ':/*滤去空格*/
			break;
		default:/*默认直接把数字压入数字栈*/
			while (ch >= '0' && ch <= '9') { /*判定为数字*/
				ex[t] = ch;                  /*把数字压入数字栈*/
				t++;                         /*数字栈栈顶指针+1*/
				/*这边的代码写得很巧妙*/
				ch = str[i];                 /*从字符串中取一个字符*/
				i++;                         /*字符数组下标+1*/
			}
			i--;
			ex[t] = '#';                     /*为每个数字加一个分隔符*/
			t++;
		}
		ch = str[i];
		i++;
	}
	/*把符号栈剩下的元素压进去*/
	while (top != 0) {
		ex[t] = stack[top];
		t++;
		top--;
	}
	ex[t] = '#';
	printf("\n原来的中序表达式:");
	for (j = 1; j < sum; j++)
		printf("%c", str[j]);
	printf("\n后缀表达式:");
	for (j = 1; j < t; j++)
		printf("%c", ex[j]);
}
void compvalue() { /*计算后缀表达式的值*/
	float stack[max], d; /*作为栈使用*/
	char ch;
	int t = 1, top = 0; /*t为ex下标,top为stack下标*/
	ch = ex[t];
	t++;
	//从左到右检查字符串
	while (ch != '#') {/*滤去#*/
		switch (ch) {
		//发现运算符,用栈顶的两个元素进行运算。
		case '+':
			stack[top - 1] = stack[top - 1] + stack[top];
			top--;
			break;
		case '-':
			stack[top - 1] = stack[top - 1] - stack[top];
			top--;
			break;
		case '*':
			stack[top - 1] = stack[top - 1] * stack[top];
			top--;
			break;

		case '/':
			if (stack[top] != 0)
				stack[top - 1] = stack[top - 1] / stack[top];
			else {
				printf("\n\t除零错误!\n");
				//exit(0);                   /*异常退出*/
			}
			top--;
			break;
		default:
			d = 0;
			while (ch >= '0' && ch <= '9') {
				d = 10 * d + ch - '0'; /*将数字字符转化为对应的数值*/
				ch = ex[t];
				t++;
			}
			top++;
			stack[top] = d;
		}
		ch = ex[t];
		t++;
	}
	printf("\n\t计算结果:%g\n", stack[top]);
}

int main() {
	trans();      //转化成逆波兰式
	compvalue();  //计算值
	return 0;
}

【C语言】算法学习·逆波兰式 逆波兰式 阅读详情

相关推荐

数据结构实验之栈与队列三:后缀式求值

数据结构实验之栈与队列三:后缀式求值 (3 + 4) × 5 - 6 就是中缀表达式 × + 3 4 5 6 前缀表达式 3 4 + 5 × 6 - 后缀表达式 中缀表达式(中缀记法) 中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。 虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式...

加油鸭 1039

【输入输出和表达式】逆序输出三位正整数

本关任务:编写程序,输入一个三位正整数,程序逆序输出该整数。例如,输入是123,逆序输出该整数,即321。

[] 939

Windows10系统添加虚拟网卡(Microsoft Loopback Adapter)的方法

1、按下win + R键,在其中输入:hdwwiz,然后 (enter) 2、点击下一步即可 3、其次选择【网络适配器】,然后点击【下一步】。 4、在厂商处选择Microsoft,网络适配器处选择【Microsoft Loopback Adapter】选项 ,点击【下一步】。 5、通过上面几个步骤的设置后,一块虚拟网卡的安装设置就算是完成了。 ...

一个懒鬼的博客 2万+

使用栈解决逆波兰表达式(后缀表达式)

逆波兰表达式又称逆序表达式,即运算符号出现在数字的后面。 主要形式为:解决思路: 逆波兰表达式解决的主要思路是利用弹栈、入栈的思想,当遇到‘+、-、*、/’等运算符的时候,在栈中弹出栈顶的两个数据进行运算,然后将运算的结果压入栈。LeetCode上面的一道例题: 值得注意的问题是,在处理‘-、/’这两个操作的时候,顺序问题很重要,先出栈的元素做为被操作数在操作符的后面。实现代码如下:impor

m0_37723587的博客 1212

华为云Stack 8.X 流量模型分析(一)

​ 当内部需要提供对外服务时(如对外发布Web网站),外部地址发起主动连接,由路由器或者防火墙上的网关接收这个连接,然后将连接转换到内部,此过程是由带有公网IP的网关替代内部服务来接收外部的连接,然后在内部做地址转换,此转换称为DNAT,主要用于内部服务对外发布。​ 内部地址要访问公网上的服务时(如Web访问),内部地址会主动发起连接,由路由器或者防火墙上的网关对内部地址做个地址转换,将内部地址的私有IP转换为公网的公有IP,网关的这个地址转换称为SNAT,主要用于内部共享IP访问外部。

Ciyaso的博客 3241

无源低通滤波器

无源RC滤波器“滤除”不需要的信号,因为它们分离并允许仅通过其频率的正弦输入信号,最简单的是无源低通滤波器网络。在低频应用(高达100kHz)中,无源滤波器通常使用简单的RC(电阻-电容)网络构建,而高频滤波器(高于100kHz)通常由RLC(电阻-电感-电容)元件制成。无源滤波器由电阻器、电容器和电感器等无源元件组成,没有放大元件(晶体管、运算放大器等),因此没有信号增益,因此它们的输出电平始终小于输入。滤波器是根据它们允许通过它们的信号的频率范围来命名的,同时阻挡或“衰减”其余部分。

weixin_44448586的博客 1万+

逆波兰算法

介绍一下逆波兰算法 能举一个逆波兰算法应用的运算示例吗?

m0_62574889的博客 834

Redis中什么是Big Key(大key)问题?如何解决Big Key问题?

通俗易懂的讲,Big Key就是某个key对应的value很大,占用的redis空间很大,本质上是大value问题。key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。用几个实际的例子对大Key的特征进行描述:● 一个String类型的Key,它的值为5MB(数据过大); ● 一

weixiaohuai的博客 3万+

【数据结构及算法】1.将表达式转换成逆波兰式

一、题目 ◆3.21③ 假设表达式由单字母变量和双目四则运算算符构成。试写一个算法,将一个通常书写形式且书写正确的表达式转换为逆波兰式。 实现下列函数:char *RPExpression(char *e);/* 返回表达式e的逆波兰式 */ Stack是一个已实现的栈。可使用的相关类型和函数:typedef char SElemType; // 栈Stack的元素类型Status Ini...

weixin_30241919的博客 2591

51单片机也能玩转GC9A01彩屏?超详细移植指南与性能优化技巧

本文详细介绍了如何在51单片机上高效驱动GC9A01彩屏,包括硬件连接优化、SPI模拟驱动、内存管理策略及高级刷新技术。通过分段缓冲、颜色压缩和差异化刷新等技巧,显著提升显示性能,使51单片机也能流畅运行240x240分辨率的彩色TFT屏幕。

hp777的博客 189

西门子PLC编程之⑦编程开始之点位配置及注释

紧接上篇,点位梳理后,进入PLC编程。1、新建工程,配置系统模块2、配置I点并做中文符合,直接上中文,smart支持中文点位编程,用起来很方便。3、配置Q点并做中文符合5、配置AIW模拟量输入点,配置AQW模拟量输出点并做中文符合6、配置手动启动辅助触点,并做中文符合7、 配置自动启动辅助触点,并做中文符合8、 配置传感器浮点型数据变量点位,并做中文符合9、配置系统运行参数设置区点位,做中午符合,做掉电保持.....................

学技术,人生不误——谁也是寂寞宇宙里的流星,只是你的坚持决定了你划过的痕迹。而且,铸造了普遍里的你的唯一。 4888

将表达式转换成逆波兰式

一、题目 ◆3.21③  假设表达式由单字母变量和双目四则运 算算符构成。试写一个算法,将一个通常书写形式 且书写正确的表达式转换为逆波兰式。 实现下列函数: char *RPExpression(char *e); /* 返回表达式e的逆波兰式 */ Stack是一个已实现的栈。 可使用的相关类型和函数: typedef char SElemType; // 栈St

xinda的博客 3358

Mstar的Monitor方案OSD 菜单制作(五)——icon绘制

Mstar的Monitor方案(五)————绘制icon

android 系统定制开发那些事 1807

【数据结构】C++将一个书写正确的表达式转换为逆波兰式

设表达式由单字母变量、双目运算符和圆括号组成(如:“(a*(b+c)-d)/e)”。试写一个算法,将一个书写正确的表达式转换为逆波兰式。

standingflower的博客 1655

FC7300 SPI MCAL配置引导

Example - QMI8A01z外设:Example - QMI8A01z外设:

舊梦的博客 257

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

中缀表达式转为逆波兰式并求值(牛客NC137-表达式求值-C++实现)

今天刷牛客遇到一个表达式求值的题,题目链接如下: 牛客NC137-表达式求值 这道题与Leetcode 224-基本计算器类似,但Leetcode这道题没有要求乘法 涉及到编译原理的内容,后缀表达式计算起来比较容易,复习了一下将中缀表达式转化为后缀表达式的方法。 ①要用到两个stack:一个放数字、一个放运算符,由于数字可能有多位,且存在运算符栈顶pop后向数字栈push的情况,因此两个stack数据类型定义为string。 ②由于放数字的栈存放最后后缀表达式,且需要一次弹出逆序,果断一开始就用queue来

powerof10的博客 989

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

逆波兰式

文章目录逆波兰式定义 逆波兰式 也叫后缀表达式(运算符写在操作数之后) 定义 表达式E的后缀形式可以如下定义: 如果E是一个变量或常量,则E的后缀式是E本身。 如果E是E1 op E2形式的表达式,这里op是任何二元操作符, 则E的后缀式为E1’E2’ op, E1’和E2’分别为E1和E2的后缀式。 如果E是(E1)形式的表达式, 则E1的后缀式就是E的后缀式。 ...

fgh123的博客 1102

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

栈应用之逆波兰式

1.也称中缀表达式转化为后缀表达式 其思想为: (1)首先,需要分配2个栈,栈s1用于临时存储运算符(含一个结束符号),此运算符在栈内遵循越往栈顶优先级越高的原则; 栈s2用于输入逆波兰式,为方便起见,栈s1需先放入一个优先级最低的运算符,在这里假定为'#';   (2)从中缀式的左端开始逐个读取字符x,逐序进行如下步骤:       1.若x是操作数,...

zhaojin0718的博客 867

数据结构课程设计项目3:算术表达式求解-预习报告

目录 一、题目 二、需求分析 三、知识补充 四、编程语言 一、题目 项目2:算术表达式求解 【问题描述】 设计一个简单的算术表达式计算器。 【基本要求】 实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入). 【测试数据】 (30+2*70)/3-12*3 5+(9*(62-37)+15)*6 要求自行设计非法表达式,进行程序测试,以保证程序的稳定运行。 【实现提示】 可以设计以下辅助函数 status isNumber(char ReadInChar); //视ReadIn...

qq_52764169的博客 1013

分治递归逆序数_士说新语 | 逆掀起波兰,抛弃了我~~逆波兰式到底是怎么来的...

这是北航士谔书院的第 1044篇推送相信很多同学都还记得,曾几何时,在我们的数据结构课程中,有着这样一道题对于这道题的算法,很多同学都选择了直接背下来,更有同学好奇这样一种算法是怎么发明出来的。其实,对于这种算法,我们有着一种通俗的理解方法。但是,为了让同学们更好地理解这种算法,我们先静下心来分析一下,我们通常所说的“计算算式”到底是怎样一个流程。我们不妨以A+B*(C-D)-E*...

weixin_35399360的博客 371

【每天一道算法题】栈的应用:将中缀表达式转为后缀表达式以及后缀表达式求值(附动图,源码,讲解最详细,没有之一)

🌱本专栏将会从基础开始,循序渐进,每天刷一道算法题,也请大家多多支持。数据结构虽然难,但只要肯坚持,一定能学好,希望大家都能够从中获益。 📫专栏地址: 🍇每日一道算法题专栏 🍉数据结构专栏 📫本专栏的所有代码都将更新在Gitee上,项目地址:项目地址 📫相关数据结构演示软件:链接地址 📫数据结构在线演示地址:https://visualgo.net/zh https://algorithm-visualizer.org/ 准备好了吗 Let’s go! 1 栈在表达式.

Learning_xzj的博客 3345

数据结构与算法_栈——逆波兰表达式求值 _python实现

先告诉你两个知识点: 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前,这里所说的表达式就是我们平时进行数学运算时所用的数学表达式。 后缀表达式就是标题所说的逆波兰表达式,和我们平时把运算符号位于操作数之间不同,后缀表达式将运算符置于操作数之后。 举例说明:6-1+3*2 = 11就是一个中缀表达式。 对应的波兰式,即前缀表达式为:[’-’, ‘6’, ‘1’, ‘*’, ‘+’ ,‘3...

qq_44273739的博客 717

JAVA数据结构—表达式

表达式前缀表达式简单介绍前缀表达式的计算机求值中缀表达式后缀表达式简单介绍后缀表达式的计算机求值中缀表达式转后缀表达式 前缀表达式 简单介绍 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前 举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 前缀表达式的计算机求值 从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式

qq_49069362的博客 168
上一篇: 递归学习笔记
下一篇: [数据结构]程杰《大话数据结构》循环链表代码
ilikeprograming
博客等级 码龄14年 46粉丝 18原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值