在介绍前缀表达式和后缀表达式之前我们先说我们最熟悉的中缀表达式:例如,(3+4)*5-6,这就是中缀表达式,是人经常使用的运算表达式,最容易让人理解,但是对于计算机来说就不太友好了,计算机对前缀表达式和后缀表达式(也叫逆波兰式)比较好处理,上述例子中的中缀表达式对应的前缀表达式和后缀表达式分别是:' -*+3456 '   和 '34+5*6- ' ,那么我们怎样通过中缀表达式转换成前缀或后缀表达式从而写出算法让计算机计算这个表达式呢,为大家介绍一种比较简单的方法,使用二叉树的遍历方法。

将中缀表达式转换为前缀表达式

第一步:以(3+4)*5-6为例,显然我们可以将这个表达式大致看作三个部分组合而成:(3+4)

5 ,6 这三个部分以及其余的运算符组成 ,相当于可以看作是a*b-c。

第二步:先画出优先级最高的运算表达式,在上述例子中优先级最高的是(3+4),因此我们先画这个部分的二叉树。将运算符左边的数字作为左孩子,右边的数字作为右孩子,运算符号为根节点(不要括号)。如下图所示:

第三步:接下来再找剩下的表达式中优先级最高的表达式,由于我们已经 将(3+4)画好了,所以就将它看为一个整体a,剩下的表达式中最高的优先级表达式为a*5,因此我们接下来画出a*5。相同的方法,先将运算符 * 左边的数字a当作左子树,将右边的数字5作为右子树,将运算符*作为根节点,如下图所示:

第四步:再从剩余的表达式中找出最高优先级的表达式,将已经画出来的表达式看作一个整体 b,剩下的表达式就为 ' b-6 ',继续重复将运算符左边的数字作为左孩子,右边的数字作为右孩子,运算符 ' - '作为根节点,画出二叉树,如下图所示:

至此就完成了中缀表达式的二叉树形式,就算有更复杂的表达式也是利用这种方法画出来,我们现在要的是前缀表达式和后缀表达式,前缀表达式的求法:将中缀表达式的二叉树形式进行前序遍历。后缀表达式的求法:将中缀表达式的二叉树形式进行后序遍历。因此利用大家学过的二叉树遍历的知识很快就可以得到前缀表达式为:'-*+3456',后缀表达式为:'34+5*6-'。

以上操作就将我们熟悉的表达式转换成了方便计算机操作的表达式(虽然看起来怪怪的),那么怎样让计算机帮我们算出这个表达式的值呢?那就是利用栈。

用前缀表达式进行计算的思路:

1:我们先将得到的前缀表达式以字符串的形式保存在一个数组中

2:从最后一位开始向前遍历,如果是数字就将该数字进栈

3:如果是运算符就不进栈,而是将栈中的栈顶元素和次栈顶元素出栈,并将                              这两个元素和这个运算符进行运算,再将得到的结果进行入栈操作,继续向前                         遍历重复第三个步骤,直到字符串遍历完为止。

就像刚刚举的例子:前缀表达式为' -*+3456 ',先将6,5,4,3进栈,当遍历到'+'运算符时,将3,4出栈,且进行 3+4 运算,将结果7进栈 ,继续遍历到 ' * '运算符,将7 和 5 出栈,并进行 7*5 运算,将结果35 进栈 ,继续遍历 ' - '运算符,将35 和 6 出栈并进行  35-6 运算,将结果29进栈,由于已经遍历完前缀表达式,所以最后的结果就是栈顶元素,取出即可。代码如下:

#include <stdio.h>
#define MAXSIZE   10
struct Stack                //定义栈的结构体
{char arr[MAXSIZE];int top;
}stack;void Push_stack(char num)            //压栈操作即进栈
{if(stack.top < MAXSIZE){stack.top++;stack.arr[stack.top] = num;}else printf("stack over flow!\n");
}void Pop_stack()              //出栈操作
{if(stack.top >= 0){stack.top--;}elseprintf("stack under flow!\n");
}int Count(char a[],int len)         //计算表达式
{stack.top = -1;             //初始化栈顶指针int result;for(int i = len-1; i >= 0; i--)          //从末尾开始遍历前缀表达式{if(a[i] >= '0' && a[i] <= '9')     //如果是数字字符就进栈Push_stack(a[i]);else if (a[i] == '+')             //如果是+运算符就进行+运算,并将两个运算的数字出栈{result = (stack.arr[stack.top--] - '0') + (stack.arr[stack.top] - '0');Pop_stack();Push_stack(result + '0');}else if(a[i] == '-')             //如果是-运算符就进行-运算,并将两个运算的数字出栈{result = (stack.arr[stack.top--] - '0') - (stack.arr[stack.top] - '0');Pop_stack();Push_stack(result + '0');}else if(a[i] == '*')             //如果是*运算符就进行*运算,并将两个运算的数字出栈{result = (stack.arr[stack.top--] - '0') * (stack.arr[stack.top] - '0');Pop_stack();Push_stack(result + '0');}else if(a[i] == '/')             //如果是/运算符就进行/运算,并将两个运算的数字出栈{result = (stack.arr[stack.top--] - '0') / (stack.arr[stack.top] - '0');Pop_stack();Push_stack(result + '0');}}return result;                //由于我将每次的结果都进行了保存,因此将结果返回即可
}int main(int argc, char *argv[])
{ char str[] = "-*+3456";                      //前缀表达式int len = sizeof(str)/sizeof(str[0]);       //求出前缀表达式字符串长度printf("result = %d\n",Count(str,len));return 0;
}

使用栈计算前缀表达式相关推荐

  1. 计算前缀表达式与后缀表达式

    前缀表达式:从后往前扫,遇到操作数入栈.遇到字符时取两栈顶元素进行相应运算后结果入栈. 后缀表达式:与上类似,只是是从前往后扫. 求前缀表达式的值 (25 分) 算术表达式有前缀表示法.中缀表示法和后 ...

  2. 有趣的数据结构算法10——后缀表达式(PRN)介绍及利用栈计算后缀表达式的结果

    有趣的数据结构算法10--后缀表达式(PRN)介绍及利用栈计算后缀表达式的结果 解题思路 实现代码 GITHUB下载连接 在前一天已经利用栈完成2进制到8进制的转换.但是栈的应用方面还有很多,本次我将 ...

  3. C语言计算前缀表达式

    算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4.请设计程序计算 ...

  4. C++做四则运算的MFC计算器(二)栈转换和计算后缀表达式

    上篇写了MFC界面搭建,这篇就写实现计算.涉及到数据结构,对新手很不友好. 虽然是MFC程序,但是能灵活地分离后台代码,自行构建控制台程序. 上一篇文章链接:C++做四则运算的MFC计算器(一)MFC ...

  5. 3-07. 求前缀表达式的值(25) (ZJU_PAT数学)

    题目链接:http://pat.zju.edu.cn/contests/ds/3-07 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,比如2+3*(7 ...

  6. 7-21 求前缀表达式的值 (25 分)(思路详解)

    一:题目 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4.请设 ...

  7. 7-211 求前缀表达式的值 (25 分)

    7-211 求前缀表达式的值 (25 分) 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * ...

  8. 中缀表达式/后缀表达式/前缀表达式

    1:什么是中缀表达式,前缀表达式,后缀表达式? 正如我们常常潜意识认为我们所说的数字都是十进制,对于数字的其他进制感觉不正确一样,其实只是我们不熟悉而已,其他进制其实也不过就是一种对数据的表达方式而已 ...

  9. 中缀、后缀、前缀表达式

    一.简介 对于1+((2*3)-4)/2 的数学表达式怎么求值? 分析: 数学表达式求值有优先级,不能简单的从左往右依次计算, 需要从优先级高的开始计算 中缀表达式是一种通用的算术或逻辑公式表示方法, ...

最新文章

  1. git push代码时的‘git did not exit cleanly (exit code 1)‘问题解决
  2. 上去很美的 Serverless 在中国落地的怎么样了?
  3. java is instance of_详谈Java中instanceof和isInstance的区别
  4. PHP源代码后门事件后续:用户数据库遭泄露或是元凶
  5. css 怎么设置盒子水平居中,用一段css实现盒子垂直水平居中方法(8种)-案例
  6. oracle装一半报错要卸掉,OpenSUSE下oracle11gR2的安装卸载
  7. sqlite3---终端操作
  8. 她很忙怎么关心_老公工作忙怎么关心 抓好三个时间点
  9. 阿里月饼事件,猿方怎么看?
  10. java初级项目 小说_webmagic项目实战(爬小说网站)
  11. Android 桌面快捷方式
  12. OSChina 周五乱弹 ——什么样的工作每天都有艳遇
  13. 带有神经网络的梯度消失(Vanishing gradients with RNNs)
  14. HDU 1507 Uncle Tom's Inherited Land(最大匹配+分奇偶部分)
  15. Make Product Equal One(思维)
  16. 微信小程序登录 获取头像不显示
  17. TensorFlow调试之一种很笨但行之有效的调试方案
  18. 算法精解_C语言 链表_单链表(接口定义+类型实现)
  19. TMS WEB Core开发Web应用优势说明
  20. 比较流行的数据分析工具合集

热门文章

  1. 达梦数据库的模式、状态介绍
  2. 虚拟化--002 HVM提示
  3. FPGA实现HDMI显示图片(1)
  4. JVM年轻代(young generation)老年代(old generation tenured)持久代(permanent generation)GC...
  5. Numpy:数组对象(Ndarray)的定义和创建
  6. 安装stable-diffusion时gfpgan安装失败
  7. 4G通信模块在嵌入式ARM Linux下的应用
  8. 六种基本网络拓扑结构
  9. 飞机飞行仪表行业研究及十四五规划分析报告
  10. android 蓝牙相关广播,Android通过广播接收器BroadcastReceiver监听蓝牙连接变化