后缀表达式求值比较简单,基本过程为:遇到数字则进栈,遇到运算符则出栈俩数字然后计算结果,再把结果入栈,过程比较简单,不再复习了,下面着重记录中缀表达式求值

中缀表达式求值可以先将中缀转后缀,再用后缀计算结果,但是,有点太麻烦,而另一种方式是利用两个栈直接求值,思想与上一个笔记中缀转后缀几乎一样,但稍有差别,中缀表达式求值基本过称为:

定义两个栈,stack1存储数字,stack2存储运算符,将字符串str元素一个个扫描,遇到数字型则进栈stack1,遇到运算符型,则要看看栈stack2栈顶元素运算符优先级是否比自己大或等于,如果真比自己大,那么那个运算符出栈,假设出栈是运算符a,那么此时从stack1中出栈两个数字b、c参与运算,把运算结果进栈stack1,此时此字符还不能进栈,如果栈顶优先级还比自己大或等于,那么那个栈顶运算符还要拿出来运算,直到有小于自己的自己才进栈;遇到‘(’直接进stack2,遇到’)’,则就要把这一对括号之间运算符都一个个拿出来运算,当str[i]读到’\0’那么扫描结束,结束后还要注意stack2里应该还有一个运算符,于是还要多加一步运算,最终stack1中剩一个数,那就是最后结果

实际上,以上都是基于每个数都是一位数组成的,即形如3*(2+4)-2而不是形如30*(20+44)-2,下面的程序也是基于一位数,但是一位数的程序编制好了后,只需要稍微调整读取字符就可以应用任意表达式了,为了深刻理解中缀表达式求值,这里不考虑多位数,只考虑能体现核心算法的一位数型

#include <stdio.h>
#include <stdlib.h>
float Cal(char a,float b,float c)//运算函数,a为运算符,b、c分别为两数
{switch(a){case '+':return (b+c);break;case '-':return (b-c);break;case '*':return (b*c);break;case '/':return (1.0*b/c);break;}
}int main(void)
{float stack1[200];//存放数字栈char stack2[100];//存放运算符栈int top1=-1,top2=-1;int i = 0;char str[200];char a;float b,c;FILE *fp=fopen("data.txt","r");//使用文件读表达式,省得每次测试都要输fscanf(fp,"%s",str);printf("%s\n",str);while(str[i] != '\0')//一个字符一个字符来{if(str[i] == '+' || str[i] == '-')//如果str[i]是加号或减号,那么栈顶运算符可以拿出来运算了{if(top2==-1)//若栈表示没有运算符,自己是第一个,故须运算符入栈2{stack2[++top2]=str[i];}else{while(stack2[top2] == '+' || stack2[top2] == '-' || stack2[top2] == '*' || stack2[top2] == '/'){a=stack2[top2--];//取出一个数字c=stack1[top1--];//再取出一个数字b=stack1[top1--];//栈2顶运算符拿出来stack1[++top1]=Cal(a,b,c);//运算结果要入栈1printf("\n%f%c%f=%f\n",b,a,c,stack1[top1]);//输出中间运算过程}stack2[++top2]=str[i];//运算完了之后该运算符要入栈2}}else if(str[i] == '*' || str[i] == '/')//如果str[i]是乘号或除号,则只有栈顶也是乘除号时才需要计算{if(top2==-1)//同上{stack2[++top2]=str[i];}else{while(stack2[top2] == '*' || stack2[top2] == '/'){a=stack2[top2--];//同上c=stack1[top1--];//同上b=stack1[top1--];//同上stack1[++top1]=Cal(a,b,c);//同上printf("\n%f%c%f=%f\n",b,a,c,stack1[top1]);//同上}stack2[++top2]=str[i];//同上}}else if(str[i] == '(')//如果str[i]是左括号则直接压入栈2{stack2[++top2]=str[i];}else if(str[i] == ')')//如果str[i]是右括号,则计算第一个左括号前的所有操作符,最后将此左括号直接弹出{while(stack2[top2] != '('){a=stack2[top2--];c=stack1[top1--];b=stack1[top1--];stack1[++top1]=Cal(a,b,c);printf("\n%f%c%f=%f\n",b,a,c,stack1[top1]);}stack2[top2--];//弹出}else//如果str[i]不是操作符则直接进去{stack1[++top1]=str[i]-'0';//数字,转为整数}i++;}while(top2!=-1)//遍历后如果栈不为空,计算剩下操作符{a=stack2[top2--];c=stack1[top1--];b=stack1[top1--];stack1[++top1]=Cal(a,b,c);printf("\n%f%c%f=%f\n",b,a,c,stack1[top1]);}printf("\n结果:%f\n",stack1[top1]);return 0;
}data.txt中数据:
3*(2+4)-2

栈应用:中缀表达式求值相关推荐

  1. 数据结构栈之中缀表达式求值(实现计算器综合计算)

    一.思路分析: 1.通过一个index值(索引),来遍历我们的表达式. 2.如果我们发现是一个数字,就直接入数栈. 3.如果发现扫描到是一个符号,就分如下情况: (1).如果发现当前的符号栈为空,就直 ...

  2. leetcode 282. Expression Add Operators | 282. 给表达式添加运算符(中缀表达式求值)

    题目 https://leetcode.com/problems/expression-add-operators/description/ 题解 中缀表达式求值问题,参考:leetcode 227. ...

  3. leetcode 227. Basic Calculator II | 227. 基本计算器 II(中缀表达式求值)

    题目 https://leetcode.com/problems/basic-calculator-ii/ 题解 这道题是 中缀表达式求值 的简化版(因为没有左右括号运算),不过输入的形式有两个处理起 ...

  4. C++代码实现中缀表达式求值(基于中缀表达式转后缀表达式)

    C++代码实现中缀表达式求值(基于中缀表达式转后缀表达式) 样例输入:3*(2+5) 样例输出:21 代码:#include <bits/stdc++.h> using namespace ...

  5. DSOJ 中缀表达式求值

    题目链接 #include<stdio.h> //中缀表达式求值 #include<string.h> #include<stdlib.h> #define MAX ...

  6. Python实现中缀表达式求值

    一.思路 有些类似于先把中缀表达式转化为后缀表达式,然后再对后缀表达式求值.但是因为我们最终只需要求出来的值,不想得到后缀表达式,所以就一边遍历一边计算了.关键点在于,我们借助两个栈,一个栈存放操作数 ...

  7. 栈实现算术表达式求值

    算术表达式求值 利用栈求解的一个典型的问题是算术表达式求值,例如:"3+4*2-(1+1)#",这样的表达式计算,在计算过程中,不是读到一个运算就立即计算,而是要与后面的运算符进行 ...

  8. leetcode 224. Basic Calculator | 224. 基本计算器(中缀表达式求值)

    题目 https://leetcode.com/problems/basic-calculator/ 题解 中缀表达式求值,之前学数据结构的笔记: class Solution {public int ...

  9. php表达式求值,PHP实现基于栈的后缀表达式求值功能

    本文实例讲述了PHP实现基于栈的后缀表达式求值功能.分享给大家供大家参考,具体如下: 后缀表达式概述 后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左 ...

最新文章

  1. python使用matplotlib可视化、使用matplotlib可视化scipy.misc图像、自定义使用RdYIBu色彩映射、将不同亮度映射到不同的色彩
  2. OPENCV裁剪图片
  3. 取消 AndroidStudio 启动时自动打开上次关闭的项目
  4. 云软件——艺术字符设计!【推荐】
  5. 一步步通过命令行cl.exe编译Windows程序
  6. windows下github 出现Permission denied (publickey)
  7. 华硕台式机重装系统教程方法
  8. 使用RabbitMQ做的一些工作及经验教训
  9. c语言程序不知道头结点输出链表,C语言,不带头结点的链表,利用头插法存入信息,然后输出,没有error,却运行不了,求大神指点...
  10. 8、ns-3可视化工具
  11. LeetCode 答案(Easy)(601-700)
  12. 路由器无线模式与信道检测
  13. 使用c语言编写词法分析程序,用C语言编写一个简单的词法分析程序
  14. 目录扫描暴力破解网站管理员密码
  15. 中文分词技术(中文分词原理)
  16. Cannot find module /node_modules/cz-conventional-changelog
  17. mac 重启php-fpm
  18. 2018千元内的UGP VR一体机开箱评测:ugp vr一体机怎么样真的好吗?
  19. kinect for windows - 初认识
  20. Android的adb命令 查看sqlite命令

热门文章

  1. SVN本地服务器搭建教程
  2. 机器学习算法【11】--推荐系统实战
  3. 数据库的三级模式结构
  4. 支架预压弹性变形值计算_支架预压方案介绍 支架预压时间要多久
  5. win2008服务器稳定性配置,windows-server-2008-r2 – 如何配置Remoteapp服务器以提高稳定性...
  6. Maven------打包
  7. 阿里 P8 高级架构师年入百万,到底什么水平?
  8. C# Excel 行高,列宽,合并单元格,单元格边框线,冻结(转载) - 关于C#操作EXCLE常见操作比较全的
  9. UNIX系统关机发送SIGTERM和SIGKILL信号流程
  10. ACM练级日志:微软编程之美比赛测试赛-3(高精度相关)