5、栈应用-表达式求值

embedded/2024/12/27 5:48:11/

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

表达式例如: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); // 继续接收下一个字符输入c = getchar();// 结束匹配break;case '=':// 移除运算符栈顶的运算符  () 和 \n和\n相遇Pop(OPTR,&x);// 继续接收下一个字符输入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';c = getchar();}// 接收完毕将数据入栈		Push(&OPND,d);	 } else if(c == '\b'){// c为退格符 -- 有待完善 }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;
}

        


http://www.ppmy.cn/embedded/148544.html

相关文章

Codesoft许可证迁移到新计算机的操作步骤

随着科技的不断发展&#xff0c;我们时常需要升级或更换计算机设备以适应更高的工作要求。然而&#xff0c;在迁移至新计算机时&#xff0c;如何确保Codesoft软件的许可证能够顺利转移并继续在新设备上使用&#xff0c;成为许多用户关心的问题。本文将为您详细介绍Codesoft许可…

Redis 初相识:开启缓存世界大门

Redis 概述 什么是 Redis Redis 是一个开源&#xff08;BSD 许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以充当数据库、缓存以及消息中间件等多种角色。从数据存储角度来看&#xff0c;它基于内存&#xff0c;通过键值对的方式来存储各种类型的…

GA-BP回归-遗传算法(Genetic Algorithm)和反向传播神经网络(Backpropagation Neural Network)

GA-BP回归详细介绍 源码 什么是GA-BP回归&#xff1f; GA-BP回归&#xff08;遗传算法-反向传播回归&#xff0c;Genetic Algorithm-Backpropagation Regression&#xff09;是一种结合了**遗传算法&#xff08;Genetic Algorithm, GA&#xff09;和反向传播神经网络&#x…

基于矩阵乘积态的生成模型:量子力学与生成任务的结合

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月23日11点02分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 文章源链接(有视频)&#xff1a;Aspir…

2024财年美国EB1A和NIW移民项目获批数据发布,获批率连续下跌,原因在哪?

今天我们来关注一下2024年美国移民局最新发布的职业移民数据&#xff0c;看看这些数据背后透露出的趋势和问题。 2024财年&#xff0c;美国移民局公布了职业移民的申请和审批数据。我们来看看两个关键的移民类别——EB1-A和NIW的情况。 ✅2024年一季度&#xff1a; ✅2024年二…

Eureka学习笔记-客户端

Eureka学习笔记 客户端 模块设计 Applications &#xff1a;保存了从 Eureka Server 获取到的服务信息&#xff0c;相当于 Eureka Client 端的服务列表缓存。InstanceInfo &#xff1a;维护了自身服务实例的信息&#xff0c;注册和心跳时需要用到。QueryClient &#xff1a;负…

大恒相机开发(3)—大恒相机工业检测的实际案例

大恒相机工业检测的实际案例 工业检测的实际案例图像采集性能优化技巧工业环境下的稳定性 工业检测的实际案例 以下是一些使用大恒相机进行工业检测的实际案例&#xff1a; 多特征光学成像系统&#xff1a; 在这个案例中&#xff0c;使用大恒相机构建了一个全方位、多特征的图…

【主动噪声控制】次级通道的在线辨识

目录 1. 次级通道的概念 2. 在线辨识的概念 3. 为什么需要次级通道的在线辨识 4. 在线辨识的实现方法 5. 次级通道在线辨识的步骤 6. 在线辨识的挑战与解决方案 7. 总结 在主动噪声控制&#xff08;Active Noise Control, ANC&#xff09;系统中&#xff0c;次级通道的在…