5、栈应用-表达式求值

本章内容使用上述栈结构函数,来完成表达式求值操作。

表达式例如:3*(7-2)  或者 (0-12)*((5-3)*3+2)/(2+2) 。

1、实现思路

        a、建立OPTR(运算符)和OPND(数字)两个栈,后输入字符串以'='结束

        b、自左向右扫描表达式

                若读取到数字,直接压入操作数栈,继续处理下一个字符;
                若读取到运算符,比较栈顶算符与读取的算符的优先级:
                            栈顶算符 < 读取的算符

                                将读取的算符压入栈,继续处理下一个字符;
                            栈顶算符 > 读取的算符

                                栈顶算符出栈,从操作数栈中取出两数字,                                                                                       根据出栈算符做运算,运算结果再压入操作数栈,继续处理当前字符;
                            栈顶算符 == 读取的算符

                                  栈顶算符出栈,括号出栈不保存,继续处理下一个字符;


           c、 结束条件是算符栈已空,最后操作数栈出栈输出计算结果。

2、运算符关系表

例如:

        3*(7-2) 

        

         

             

            

        

     

    

   

   

      

        

3、代码实现

        3.1、定义全局数组存放合法的运算符

static char opts[] = {'+','-','*','/','(',')','\n'};

        3.2、实现函数判断当前字符是不是运算符        

// 定义函数,判断当前的字符是不是运算符,如果是返回在运算符数组中的下标,如果不是返回-1 
int isOpt(const char ch)
{	
	int len = sizeof(opts) / sizeof(char);
	int i;
	for(i=0;i<len;i++)
	{
		if(opts[i] == ch)
		{
			return i;
		}
	}
	return -1;	
} 

        3.3、实现函数判断栈顶运算符和当前输入运算符的关系

// 定义函数获取栈顶运算符和当前输入运算符之间的关系
char Precede(SElemType ch1,SElemType ch2)
{
	// 根据运算符优先级表格,使用二维数组存储字符之间的关系 
	static char optsRelationArr[7][7] = {
		{'>','>','<','<','<','>','>'},
		{'>','>','<','<','<','>','>'},
		{'>','>','>','>','<','>','>'},
		{'>','>','>','>','<','>','>'},
		{'<','<','<','<','<','=',-1},		
		{'>','>','>','>',-1,'>','>'},		
		{'<','<','<','<','<',-1,'='}
	};
	
	// 获取两个字符的排序下标 
	int idx1 = isOpt(ch1);
	int idx2 = isOpt(ch2);
	
	// 字符不存在直接返回-1 
	if(idx1 < 0 || idx2 < 0)  return -1; 
	
	// 合法返回对应关系
	return optsRelationArr[idx1][idx2]; 
}

        ​​​​3.4、实现函数根据运算符求+-*/结果                

// 定义函数进行算数运算
SElemType Operator(SElemType a,SElemType x,SElemType b) 
{
	switch(x)
	{
		case '+':
			return a + b;
		case '-':
			return a - b;
		case '*':
			return a * b;
		case '/':
			return a / b;	
	}
}

        3.5、实现函数求表达式的结果

SElemType EvalueExpression()
{
	// 定义操作数栈和运算符栈
	SqStack OPND,OPTR;
	// 定义变量存储 计算中的两个数据
	SElemType a,b;
	// 定义变量存储数据出现多位数据的运算中间量  12  45这类操作数
	SElemType d;
	// 定义变量存储 运算栈栈顶字符
	SElemType x;
	
	// 定义变量存储用户输入的字符符号
	char c;	
	
	// 初始化操作数栈和运算符栈
	InitStack(&OPND);
	InitStack(&OPTR);
	
	// 现象运算符栈中添加\n作为运算结束
	Push(&OPTR,'\n');
	x = '\n';
	
	// 接收一个字符
	c = getchar();	
	
	// 循环结束数据并运算 
	// 结束条件为 ,循环条件为相反面: !(c=='\n' && x=='\n') 
	while(!(c=='\n' && x=='\n')) 
	{			
		if(isOpt(c) >= 0)
		{			
			// c为运算符 ,比较x和c的大小
			char res = Precede(x,c);
			switch(res) 
			{
				case '<':
					// 当前运算符入栈
					Push(&OPTR,c); 
					// 继续接收下一个字符输入
					//scanf(" %c",&c);
					c = getchar();		
					// 结束匹配
					break;
				case '=':
					// 移除运算符栈顶的运算符  () 和 \n和\n相遇
					Pop(&OPTR,&x);
					// 继续接收下一个字符输入
					//scanf(" %c",&c);	
					c = getchar();	
					// 结束匹配
					break;
				case '>':
					// 移除运算符栈顶的运算符
					Pop(&OPTR,&x);
					// 移除操作数栈栈顶两个数据
					Pop(&OPND,&b);
					Pop(&OPND,&a);
					// 计算后结果入栈
					Push(&OPND,Operator(a,x,b));
					// 结束匹配 
					break;
			}
			
		}
		else if(c >= '0' && c <= '9')
		{			
			d = 0;
			// c为数字字符 -- 注意处理多个数字字符组合成一个数字的情况
			while(c >= '0' && c <= '9')
			{
				d = d * 10 + c - '0';
				// scanf(" %c",&c);	
				c = getchar();	
			}
			// 接收完毕将数据入栈					
			Push(&OPND,d);
		} 	
		else
		{			
			// 非法字符
			printf("出现非法字符\n");
			exit(OVERFLOW); 
		} 
		
		
		// 获取运算符栈顶数据,继续下一轮的运算 
		GetTop(OPTR,&x);
		
	}
	
	/***** 运算结束  *******/ 
	// 移除操作数栈 栈顶元素
	Pop(&OPND,&x);
	
	// 如果操作栈为空则结果为栈顶元素,否则表达式不正确
	if(!StackEmpty(OPND))
	{		
		printf("表达式有问题\n");
		exit(OVERFLOW);
	} 
	
	return x;	 
} 

          3.6、main函数测试结果        

int main(int argc, char *argv[]) {
	printf("请输入算数表达式,负数用(0-正数)表示:"); 
	SElemType res = EvalueExpression();
	printf("%d",res);	
	
	return 0;
}

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944050.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【软件】教务系统成绩提交工具使用步骤

【软件】教务系统成绩提交工具使用步骤 零、快速开始 安装 与大多数软件一样&#xff0c;安装步骤很简单&#xff0c;一直点击“下一步”即可快速完成安装&#xff0c;安装完成后&#xff0c;在桌面会有一个软件图标&#xff0c;双击即可打开软件主界面。 导入成绩到Excel中…

书签管理工具的使用技巧

分类与筛选技巧 多层级分类&#xff1a;创建多层级的文件夹结构&#xff0c;如先按大的主题分类&#xff0c;再在每个主题下细分小类。例如&#xff0c;先创建 “工作”“学习”“生活” 等大文件夹&#xff0c;在 “工作” 文件夹下再细分 “项目文档”“办公软件”“行业资讯…

如何安全获取股票实时数据API并在服务器运行?

以下是安全获取股票实时数据 API 并在服务器运行的方法&#xff1a; 选择合适的券商或交易平台 评估自身需求&#xff1a;明确自己的交易策略、交易品种、交易频率等需求&#xff0c;以及对 股票api 的功能、性能、稳定性等方面的要求。调研券商或平台&#xff1a;了解不同券商…

图像处理-Ch2-空间域的图像增强

Ch2 空间域的图像增强 文章目录 Ch2 空间域的图像增强Background灰度变换函数(Gray-level Transformation)对数变换(Logarithmic)幂律变换(Power-Law)分段线性变换函数(Piecewise-Linear)对比度拉伸(Contrast-Stretching)灰度级分层(Gray-level Slicing) 直方图处理(Histogram …

告别 Shuffle!深入探索 Spark 的 SPJ 技术

随着 Spark > 3.3&#xff08;在 3.4 中更加成熟&#xff09;中引入的存储分区连接&#xff08;Storage Partition Join&#xff0c;SPJ&#xff09;优化技术&#xff0c;您可以在不触发 Shuffle 的情况下对分区的数据源 V2 表执行连接操作&#xff08;当然&#xff0c;需要…

解决Springboot整合Shiro自定义SessionDAO+Redis管理会话,登录后不跳转首页

解决Springboot整合Shiro自定义SessionDAORedis管理会话&#xff0c;登录后不跳转首页 问题发现问题解决 问题发现 在Shiro框架中&#xff0c;SessionDAO的默认实现是MemorySessionDAO。它内部维护了一个ConcurrentMap来保存session数据&#xff0c;即将session数据缓存在内存…

【蓝桥杯——物联网设计与开发】基础模块8 - RTC

目录 一、RTC &#xff08;1&#xff09;资源介绍 &#x1f505;简介 &#x1f505;时钟与分频&#xff08;十分重要‼️&#xff09; &#xff08;2&#xff09;STM32CubeMX 软件配置 &#xff08;3&#xff09;代码编写 &#xff08;4&#xff09;实验现象 二、RTC接口…

API安全学习笔记

必要性 前后端分离已经成为web的一大趋势&#xff0c;通过TomcatNgnix(也可以中间有个Node.js)&#xff0c;有效地进行解耦。并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务&#xff08;多种客户端&#xff0c;例如&#xff1a;浏览器&#x…

2011-2020年各省城镇职工基本医疗保险年末参保人数数据

2011-2020年各省城镇职工基本医疗保险年末参保人数数据 1、时间&#xff1a;2011-2020年 2、来源&#xff1a;国家统计局 3、指标&#xff1a;省份、时间、城镇职工基本医疗保险年末参保人数 4、范围&#xff1a;31省 5、指标解释&#xff1a;参保人数指报告期末按国家有关…

【蓝桥杯——物联网设计与开发】拓展模块4 - 脉冲模块

目录 一、脉冲模块 &#xff08;1&#xff09;资源介绍 &#x1f505;原理图 &#x1f505;采集原理 &#xff08;2&#xff09;STM32CubeMX 软件配置 &#xff08;3&#xff09;代码编写 &#xff08;4&#xff09;实验现象 二、脉冲模块接口函数封装 三、踩坑日记 &a…

Kubernetes Gateway API-2-跨命名空间路由

1 跨命名空间路由 Gateway API 具有跨命名空间路由的核心支持。当多个用户或团队共享底层网络基础设施时,这很有用,但必须对控制和配置进行分段,以尽量减少访问和容错域。 Gateway 和 Route(HTTPRoute,TCPRoute,GRPCRoute) 可以部署到不同的命名空间中,路由可以跨命名空间…

Windows Powershell实战指南(未完成)

目前只作简单了解&#xff0c;开始吧。 一、初识Powershell 目标 初步认识 Powershell和其集成环境 Ise&#xff0c;学会基本设置 实验 我们从简单的例子开始&#xff1a;希望你能从控制台和ISE的配置中实现相同的结果。然后按照下面五步进行。 &#xff08;1&#xff09;选…

Android着色器SweepGradient渐变圆环,Kotlin

Android着色器SweepGradient渐变圆环&#xff0c;Kotlin import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.Path import android.graphics.SweepGradient import android…

项目上传到gitcode

首先需要在个人设置里面找到令牌 记住自己的账号和访问令牌&#xff08;一长串&#xff09;&#xff0c;后面git要输入这个&#xff0c; 账号是下面这个 来到自己的仓库 #查看远程仓库&#xff0c;是不是自己的云仓库 git remote -v # 创建新分支 git checkout -b llf # 三步…

SAQ问卷的定义,SAQ问卷是什么?

SAQ问卷&#xff0c;全称为可持续发展评估问卷&#xff08;Sustainability Assessment Questionnaire&#xff09;&#xff0c;是一种在线自评工具&#xff0c;其深远意义与广泛应用在当今商业环境中愈发凸显。它不仅是一种衡量企业在环境、社会和治理&#xff08;ESG&#xff…

SpringBoot获取bean的几种方式

目录 一、BeanFactory与ApplicationContext的区别 二、通过BeanFactory获取 三、通过BeanFactoryAware获取 四、启动获取ApplicationContext 五、通过继承ApplicationObjectSupport 六、通过继承WebApplicationObjectSupport 七、通过WebApplicationContextUtils 八、通…

web3基于zkEVM的L2扩容方案-Scroll

项目简介 Scroll 是2021年由华人创始团队推出的 基于zkEVM 的 以太坊ZKR扩容方案&#xff0c;不同于zkSync的语言级别兼容&#xff0c;Scroll实现了完全EVM等效&#xff0c;即字节码层级兼容&#xff0c;除了数据结构和状态树等部分&#xff0c;zkEVM看起来与以太坊完全一样&a…

深入浅出 Linux 操作系统

深入浅出 Linux 操作系统 引言 在当今数字化的时代&#xff0c;Linux 操作系统无处不在。从支撑互联网巨头庞大的数据中心&#xff0c;到嵌入智能家居设备的微型芯片&#xff0c;Linux 都发挥着关键作用。然而&#xff0c;对于许多人来说&#xff0c;Linux 仍笼罩着一层神秘的…

Python毕业设计选题:基于python的白酒数据推荐系统_django+hive

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 白酒管理 系统管理 看板展示 系统首页 白酒详情…

【赵渝强老师】MongoDB逻辑存储结构

MongoDB的逻辑存储结构是一种层次结构&#xff0c;主要包括了三个部分&#xff0c;即&#xff1a;数据库&#xff08;Database&#xff09;、集合&#xff08;Collection&#xff0c;也可以叫做表&#xff09;和文档&#xff08;Document&#xff0c;也可以叫做记录&#xff09…