前缀表达式的计算机求值特点

引例:某表达式的前缀形式为"+ -*^ABCD/E/F+GH",那么它的中缀形式为?

前缀表达式的操作

前缀表达式是一种没有括号的算术表达式,就是前序表达式,不同于中缀表达式,它把运算符写在前面,操作数写在后面,前缀表达式也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3)。后缀表达式和前缀表达式十分相似,只是后缀表达式从左往右读入计算机。
前缀表达式:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

计算过程:题目中前缀形式为:±*^ABCD/E/F+GH

  1. 首先扫描 H,是数字 入栈 ,栈中为: H
    2)扫描 G 为数字 入栈 ,栈中为:G,H
    3)扫描+ 为运算符 ,依次弹出G ,H ,得到 G+H 的结果 入栈,栈中为: G+H(在这里方便讲解 标记为 G+H)
    4)扫描 F 为数字 ,入栈 ,栈中为 F, G+H
    5)扫描 / 为运算符, 依次弹出 F,G+H ,计算F/(G+H) 的结果入栈 ,栈中为 F/(G+H)
    6)扫描 E 为数字,入栈,栈中为 E, F/(G+H)
    7)扫描 / 为运算符, 依次弹出E, F/(G+H) ,计算 E/(F/(G+H))
    8)扫描 D 为数字,入栈 栈中为:D, E/(F/(G+H))
    9)扫描 C 为数字,入栈 栈中为:C,D, E/(F/(G+H))
    10)扫描 B 为数字,入栈 栈中为:B,C,D, E/(F/(G+H))
    11)扫描 A 为数字,入栈 栈中为:A,B,C,D, E/(F/(G+H))
    12)扫描^ 为运算符,依次弹出 A,B 计算 A^B的结果入栈, 栈中为:A^B ,C,D, E/(F/(G+H))
    13)扫描为运算符,依次弹出 A^B,C 计算 A^BC的结果入栈, 栈中为:A^B* C,D, E/(F/(G+H))
    14)扫描-为运算符,依次弹出 A^BC,D 计算 A^BC-D的结果入栈, 栈中为:A^B* C-D, E/(F/(G+H))
    15)扫描+为运算符,依次弹出 A^BC-D, E/(F/(G+H)) 计算 A^BC-D+ E/(F/(G+H)) 的到结果
    最后得到的表达式为: A^B* C-D+ E/(F/(G+H))

代码实现中缀2前缀

中缀表达式转前缀表达式,利用前缀表达式求结果。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** @Auther: 我爱双面奶* @Date: 2018/7/18 22:53* @Description: 中缀(infix)表达式转波兰式(polish notation)(前缀表达式)**/
public class InfixToPNCalculate {public static void main(String[] args) {String str = "1+(6/2)-8*2+(20-4)";List<String> pnStack = infixToPn(str);int result = getResrult(pnStack);System.out.println("结果:"+result);}/*** 中缀转前缀表达式算法** 1、初始化两个栈:运算符栈opStack和存储前缀表达式栈pnStack;* 2、【反转】字符串,【从左至右】扫描中缀表达式;* 3、遇到操作数时,直接将其压入tempStack中;* 4、遇到运算符时,比较其与opStack栈顶运算符的优先级:*       4.1、如果opStack为空,或者栈顶运算符为右括号’)’,则直接将此运算符压入opStack中;*       4.2、否则,若优先级比栈顶运算符的优先级高或相等,则直接将此运算符压入opStack中;*       4.3、否则,将opStack栈顶的运算符弹出并压入到tempStack中,再次转入步骤4,与opStack中新的栈顶运算符相比较;* 5、遇到括号时:*       5.1、如果是右括号’)’,则直接压入opStack中;*       5.2、如果是左括号’(‘,则依次弹出opStack栈顶的运算符并压入tempStack中,知道遇到右括号’)’为止,此时将这一对括号丢弃;* 6、重复步骤2~5,直到表达式的最左边;* 7、将opStack中剩余的运算符依次弹出并压入tempStack中;* 8、依次弹出tempStack中的元素保存到result中,result即为中缀表达式转换所得的前缀表达式。* @param strExpression 前缀表达式* @return 后缀表达式*/public static List<String> infixToPn(String strExpression){StringBuilder stringBuilder = new StringBuilder(strExpression.trim());//将String对象转换为StringBuilder对象,为了转字符串System.out.println("中缀表达式:"+stringBuilder);stringBuilder = stringBuilder.reverse();//反转字符串List<String> pnStack = new ArrayList();//前缀表达式栈List<String> opStack = new ArrayList();//运算符栈String falg = "";char[] str = stringBuilder.toString().toCharArray();//从左往右扫描for(int i=0;i<str.length;i++ ){if(isDigit((falg+str[i]).trim())){//判断flag+当前字符是否为数字falg = (falg+str[i]).trim();if(i==str.length-1){//当当前字符是数字,并且是最后一个字符时直接存入前缀表达式栈//由于之前反转了,现在要反转回来,比如45在之前被反转为了54,需要反转回来pnStack.add(new StringBuilder(falg).reverse().toString());}}else {//当当前字符不是数字时if(falg.trim()!=""&&isDigit((falg).trim())){//将上一次的flag存入前缀表达式栈pnStack.add(new StringBuilder(falg).reverse().toString());falg="";}if(opStack.size()==0||opStack.get(opStack.size()-1).equals(")")){//对应4.1opStack.add(String.valueOf(str[i]));}else if(str[i]==')'){//对应5.1opStack.add(String.valueOf(str[i]));}else if(str[i]=='('){//对应5.2while (opStack.size()!=0){if(opStack.get(opStack.size()-1).equals(")")){opStack.remove(opStack.size()-1);break;}pnStack.add(opStack.get(opStack.size()-1));opStack.remove(opStack.size()-1);}}else if (str[i]=='*'||str[i]=='/'){//对应4.2opStack.add(String.valueOf(str[i]));}else if(opStack.get(opStack.size()-1).equals("*")||opStack.get(opStack.size()-1).equals("/")){//对应4.3pnStack.add(opStack.get(opStack.size()-1));opStack.remove(opStack.size()-1);i--;}else {//对应4.2opStack.add(String.valueOf(str[i]));}}}//对应7while (opStack.size()!=0){pnStack.add(opStack.get(opStack.size()-1));opStack.remove(opStack.size()-1);}//反转List对象Collections.reverse(pnStack);System.out.print("波兰式(前缀表达式):");pnStack.stream().forEach(x-> System.out.print(x+" "));//迭代输出System.out.println("");return pnStack;}/*** 通过前缀表达式计算结果* 1、借助中间结果栈tempStack,【从右至左】扫描表达式* 2、遇到操作数时,将操作数入tempStack栈* 3、遇到操作符时,从tempStack栈中弹出两个操作数,进行运行,然后将运算结果压入tempStack栈。* 4、重复1~3,直到pnStack为空* 5、tempStack栈剩下的最后一个元素即所求结果* @param pnStack 中间结果栈* @return*/public static int getResrult(List<String> pnStack){int result = 0;List<String> tempResultStack = new ArrayList<>();while (pnStack.size()!=0){int end = pnStack.size()-1;int resultend = tempResultStack.size()-1;if(isDigit(pnStack.get(end))){//对应2tempResultStack.add(pnStack.get(end));pnStack.remove(end);}else {//对应3if(pnStack.get(end).equals("*")) {result = Integer.parseInt(tempResultStack.get(resultend)) * Integer.parseInt(tempResultStack.get((resultend - 1)));}else if (pnStack.get(end).equals("/")){result = Integer.parseInt(tempResultStack.get(resultend)) / Integer.parseInt(tempResultStack.get((resultend - 1)));}else if (pnStack.get(end).equals("+")){result = Integer.parseInt(tempResultStack.get(resultend)) + Integer.parseInt(tempResultStack.get((resultend - 1)));}else if (pnStack.get(end).equals("-")){result = Integer.parseInt(tempResultStack.get(resultend)) - Integer.parseInt(tempResultStack.get((resultend - 1)));}pnStack.remove(end);tempResultStack.remove(resultend);tempResultStack.remove(resultend-1);tempResultStack.add(String.valueOf(result));}}// System.out.println(tempResultStack.toString());return result;}/*** 判断一个字符串是否为数值* @param str 判断的字符串* @return 返回一个boolean值*/public static boolean isDigit(String str){return str.matches("[0-9]{1,}");}}

附录

1.代码参考作者:我爱双面奶
https://note.youdao.com/ynoteshare1/index.html?id=ffe93536b1140b00bbe205282990e1ff&type=note
2.题目来自牛客网

前缀表达式的计算机求值相关推荐

  1. pnd1 c语言,c语言实现中缀后缀前缀表达式相互转化并求值

    <c语言实现中缀后缀前缀表达式相互转化并求值>由会员分享,可在线阅读,更多相关<c语言实现中缀后缀前缀表达式相互转化并求值(21页珍藏版)>请在人人文库网上搜索. 1.1)表达 ...

  2. 前缀中缀后缀表达式的计算求值

    原文在这里 表达式 前缀表达式(波兰表达式) 前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前 举例说明: (3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6 前缀表达式求值 ...

  3. R语言 表达式对象的求值 eval

    R语言 表达式对象的求值 eval 模式为 "expression"的对象在Expression objects 有具体定义.它们和引用对象的列表非常相似. > ex < ...

  4. C语言实现中缀转后缀表达式,并求值

    C语言实现中缀转后缀表达式,并求值 #include <stdio.h> #include <stdlib.h> #include <ctype.h> #inclu ...

  5. 使用栈解决的一类经典问题:表达式转换及求值;中缀表达式;前缀表达式,后缀表达式,中缀转前缀;中缀转后缀;后缀表达式求值;波兰式,逆波兰式

    文章目录 背景知识 表达式转换问题(考研经典) 一:手工转换 (1)中缀转前缀和中缀转后缀 (2)前缀转中缀和后缀转中缀 二:用栈实现表达式转换 (1)中缀转后缀 (2)中缀转前缀 表达式计算问题(使 ...

  6. 用计算机求值根号12345,【中考数学专题】特殊角的妙用——“12345模型”

    几何图形中经常会出现一些特殊角,熟悉的有30°.45°.60°等等,特殊角往往伴随着固有属性运用于题目中,也是解题思路来源之一. 比如看到30°角我们会想到 ,45°角总是跟等腰直角三角形说不清道不明 ...

  7. 中缀表达式转换为前缀及后缀表达式并求值【摘】

    它们都是对表达式的记法,因此也被称为前缀记法.中缀记法和后缀记法.它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前:中缀和后缀同理. 举例: (3 + 4) ...

  8. 【栈】【150. 逆波兰表达式求值】【中等】(需回顾)

    根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...

  9. 表达式求值(最详细分析+代码实现+表达式之间的相互转换)

    目录 一.概念 二.前缀表达式的逻辑和实现方式 1.定义 2.前缀表达式的计算机求值 3.例子 4.代码实现 三.中缀表达式的逻辑和实现方式 1.定义 2.中缀表达式规则 3.中缀表达式的计算机求值 ...

最新文章

  1. Python培训完可以找什么工作
  2. 2020 最烂密码 TOP 200 大曝光!
  3. 橡胶支座抗压弹性模量计算公式_囊谦网架生态酒店_网架抗震垫块A诚信商家-桥兴橡胶...
  4. 其实我们不需要那么大的房子
  5. android studio 连不上设备,Android Studio-设备已连接但“脱机”
  6. spring boot 带远程调试启动方式
  7. 清华大学计算机学院主页,计算机图形学基础课程主页 | 清华大学计算机系
  8. qt5.9.0调试如何查看变量的值_深入了解 Java 调试
  9. Smack Extensions用户手册
  10. Java编程思想(五) —— 多态(下)
  11. docker安装redis【网易镜像方式】
  12. oracle查询备份存储路径,Oracle 数据库备份与恢复(RMAN介绍一)
  13. 部署与发布策略 蓝绿发布
  14. java如何导出excel_JAVA如何导出EXCEL表格
  15. 基于蚁群算法的图像边缘检测
  16. flask手写汉字识别网站(已开源)
  17. 可视化正则表达式教程
  18. 计算机二级软件java_全国计算机等级考试使用的java软件版本
  19. android雪花飘落效果,【OpenGL】Shader实例分析(七)- 雪花飘落效果
  20. Android动画失效

热门文章

  1. 难得一见的机械原理动态图
  2. 小程序报错,域名不合法(request 合法域名校验出错)
  3. Centos7安装配置Docker
  4. 【资源分享】今日学习打卡--k近邻法 (k Nearest Neighbor Method)
  5. [.NET Desktop] 类似于360或者腾讯电脑管家的托盘嵌入程序(目前不稳定)
  6. Java-pdf下载加水印
  7. 云计算和python真实工资_云计算工程师工资待遇高吗?一般多少?
  8. 韩国全国断网,挖一挖背后的原因及思考
  9. S12ZVM电路设计说明
  10. DIV的高度自适应及注意问题(详细解释)(转)