首页 > 编程知识 正文

前缀中缀后缀表达式转换,数据结构后缀表达式转换过程

时间:2023-05-05 19:55:44 阅读:44314 作者:2432

计算表达式,详细解释将骑马订表达式转换为后缀表达式的步骤,针对代码实现(Java )所谓的前、中、后缀表达式,简述骑马订表达式和后缀表达式。

中缀表达式:人们常用的书写形式是骑马订形式。 例如,4*(1)2)- 3是我们平时使用的公式。 对人来说骑马订式容易理解,知道该式的计算方法,容易理解计算步骤的优先顺序,但对计算机来说,如何理解该式的优先顺序呢? (优先级是指在计算小括号内的公式后再计算乘除后的加减(后缀表达式)后缀式也称为逆波兰式,将上述例子的骑马订式变换为后缀式时,上述后缀式的运算优先级,即从左到右骑马订式后缀式步骤初始化运算符堆栈s1和中间结果堆栈s2这两个堆栈;

从左向右扫描的骑马订式;

如果遇到操作数,将其压入s2;

如果找到运算符,则比较与s1堆栈顶部运算符的优先级;

4.1 .如果S1为空,或者堆栈顶部运算符为左括号“()”,则将此运算符直接放入堆栈;

4.2 .否则,如果优先级高于堆栈顶部的运算符,则运算符也推入s1;

4.3 .否则(即,相同或更小的优先级),弹出s1栈顶的运算符并将其推入s2,然后再次移动到4.1以与新的栈顶运算符进行比较;

遇到括号时;

重复步骤2到5直到公式的最右边。

在s1中依次弹剩下的运算符,压入s2;

依次弹出s2的要素并输出。 结果的逆序是与骑马订表达式相对应的后缀表达式

举例说明

骑马订式从1 ()2)3)4)- 5变换为后缀式时,1 )2)3)4)5-

扫描的要素s1 (堆栈底-堆栈顶) s2 (堆栈底-堆栈顶)表示从1空1扫描到数字直接推入s2堆栈1s1之前为空,直接推入要素编号()从1扫描到数字直接推入s2堆栈将扫描的要素直接压入s1堆栈3 ()1)2) 3将数字直接压入s2堆栈()1)2)用方括号依次排出s1堆栈最上部的要素压入s2堆栈,

直到遇到左括号为止,废弃该括号对*(*1)2)栈顶为左括号,直接元素4 )1)2)3)数字直接压入s2栈)1)2)依次弹出右括号压入s2栈,

如果遇到左括号并放弃该括号对之前--1 2 3 4 *与堆栈顶部相比优先级不高于堆栈顶部元素,请将堆栈顶部元素弹出到s2

与新堆栈顶部元素相比,堆栈顶部将空的压入减号5-1 2 3 4 * 5的数字直接压入s2堆栈,扫描到达右端空的1 2 3 4 * 5 -扫描到达右端后,依次弹出s1堆栈中剩下的元素,进入s2堆栈/**用法: stackstringresult=infixpostexpression.switch (expression ) ) * expression:中的前缀,字符串类型*/classinfixtopossion 遍历表达式liststringlist=infixtopostexpression.to list (infixtopostexpression.to list ),将publicstaticstringswitchlist /字符串作为堆栈返回system.out.println (列表; 堆叠字符串numstack=new stack (; sackstringoperatestack=new stack (; for(intI=0; i list.size (; ()/)逐个取出列表中的元素String element=list.get(i ) I ); if(element.charat(0)='0' element.charAt(0)='9) ) /数字时直接为numstacknumstack.push ) ) element ); I; }elseif(operatestack.isempty ()//堆栈空直接将元素推入堆栈时

operateStack.push(element); i++; } else if (element.equals("+") || element.equals("-") || element.equals("*") || element.equals("/")) {// 如果为运算符 则比较优先级 if (operateStack.peek().equals("(") || operateStack.isEmpty()) {// 如果栈为空或者栈顶元素为左括号 则直接该元素压入operateStack栈中 operateStack.push(element); i++; } // 如果当前运算符高于栈顶运算符 则直接将当前运算符压入operateStack栈中 else if ((element.equals("*") || element.equals("/")) && ((operateStack.peek().equals("+")) || (operateStack.peek().equals("-")))) { operateStack.push(element); i++; } else { // 否则 当前运算符优先级不大于栈顶运算符的优先级 则将栈顶运算符弹出压入到numStack栈中 再将当前运算符与下一个栈顶元素比较优先级 则i不递增 numStack.push(operateStack.pop()); } } else if (element.equals("(")){ // 如果当前元素为左括号 则直接压入operateStack栈中 operateStack.push(element); i++; } else if (element.equals(")")) { // 如果当前元素为右括号 依次将栈顶元素弹出压到numStack栈中 直到弹出元素为左括号 然后丢弃这一对括号 while (!(operateStack.peek().equals("("))) { numStack.push(operateStack.pop()); } operateStack.pop(); i++; } } // 当中缀表达式从左到右扫描完后 执行一下步骤 // 把operateStack中剩余的元素弹出压到numStack栈中 while (!operateStack.isEmpty()) { numStack.push(operateStack.pop()); } // 再将numStack的元素顺序反转 即为后缀表达式 while (!numStack.isEmpty()) { operateStack.push(numStack.pop()); } return operateStack; } /** 静态方法:将字符串分割后返回List */ public static List<String> toList(String str) { List<String> list = new ArrayList<>(); String s = ""; for (int i = 0; i < str.length(); i++) { // 如果是运算符 直接添加到列表中 if ((str.charAt(i) >= '9' || str.charAt(i) <= '0') && str.charAt(i) != ' ') list.add(str.charAt(i) + ""); else if (str.charAt(i) >= '0' && str.charAt(i) <= '9') { // 如果该字符是数字 需要处理是不是多位数 s += str.charAt(i); // 如果字符串没有到达边界 且下一个字符也是数字就进行拼接 if (i + 1 >= str.length() || str.charAt(i + 1) < '0' || str.charAt(i + 1) > '9') { list.add(s); s = ""; } } } return list; }}

转换得到后缀表达式,对于写程序来计算后缀表达式相当简单,以下为具体的就算过程:

计算后缀表达式步骤 创建一个栈储存中间的计算结果,假如栈名为 stack从左至右扫描后缀表达式 若为数字,将数字压入到stack栈中若为运算符,依次弹出栈顶两个数字进行响应的运算,将运算结果压入stack栈中 直到扫描完后缀表达式,最后stack栈中只剩一个数,即为计算结果

举例说明

以上述后缀表达式为例:1 2 3 + 4 * + 5 -

扫描到的元素stack栈中的动态示意说明11数字直接入栈21 2数字直接入栈31 2 3数字直接入栈+1 5弹出3、2 ,将2 + 3结果压入栈中41 5 4数字直接入栈*1 20弹出5,4, 将4 * 5结果压入栈中+21弹出20,1,将1 + 20结果压入栈中521 5数字直接入栈-16弹出5,21 将21 - 5结果压入栈中

扫描后缀表达式到达右端后,satck栈中只剩一个元素为16,即最后栈中的元素为计算后缀表达式的结果

计算后缀表达式的代码实现 import java.util.*;/** 计算后缀表达式 */public class CalculateWithPostExpression { public double culculate(String str) { // 将中缀表达书转换成后缀表达式 Stack<String> stack = InfixToPostExpression.switchList(str); Stack<Number> numberStack = new Stack<>(); // 根据后缀表达式的计算步骤计算 // 1.从左到右扫描后缀表达式 // 2.若为数字就压入栈中 // 3.若为操作符则依次弹出两个栈顶元素进行响应的运算,将运算结果压入栈中 // 4.扫描结束后 栈中仅剩的一个元素即为表达式的计算结果 int count = stack.size(); for (int i = 0; i < count; i++) { // 如果为数字直接压栈 if (stack.peek().charAt(0) >= '0' && stack.peek().charAt(0) <= '9') { numberStack.push(Double.valueOf(stack.pop())); } else { // 否则 进行相应的操作 double num1 = (double)numberStack.pop(); // 弹出栈顶的数字 double num2 = (double)numberStack.pop(); switch (stack.pop()) { // 进行相应的运算 case "+" : numberStack.push(num2 + num1);break; case "-" : numberStack.push(num2 - num1);break; case "*" : numberStack.push(num2 * num1);break; case "/" : numberStack.push(num2 / num1);break; default : throw new RuntimeException("输入的表达有误"); } } } return (double)numberStack.pop(); // 返回栈中最后一个元素,即为计算结果 }} 总结

想要计算机以人们的预期来理解中缀表达式的优先级,然后计算中缀表达式,此举并不简单,但是计算后缀表达式对于写程序来实现先对简单。但是难点在于中缀表达式转换成后缀表达式,当然,如果觉得转换过程麻烦,或者不理解亦或看不懂实现转换的代码,也有直接计算中缀表达式的方法,以及代码实现,等我更新。。。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。