数据结构中缀表达式转后缀表达式以及后缀转中缀表达式
Posted ApacheMoy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构中缀表达式转后缀表达式以及后缀转中缀表达式相关的知识,希望对你有一定的参考价值。
最近一直在看数据结构这本书,我相信,对于每个程序员来说,数据结构都尤为重要。为什么要学,可以看看这位博友的认识http://blog.csdn.NET/sdkfjksf/article/details/54380659
直入主题:将中缀表达式转为后缀表达式 以及将后缀表达式转为前缀表达式的实现。
关于后缀转中缀,中缀转后缀的理论介绍,请先阅读其互转的理论知识,或者我转发的这篇文章,这里不再累赘,最好参考《数据结构与算法描述Java语言版》,接下来将会用java写。
一、首先,怎么实现中缀表达式转为后缀表达式
中缀表达式转为后缀表达式相对较为简单,对于中缀表达式转后缀,其思想是将 运算符(+-*/)往栈中放,数字就直接输出,然后通过每次扫描遇到的运算符优先级来判断出栈与入栈。直接上代码吧,代码中也有解释!
package com.liyongdada.cn; import java.util.Scanner; import java.util.Stack; public class StackTest { public static void main(String[] args) { // TODO Auto-generated method stub Character token; String exep; int i=0; //下面一句需要jre1.5 Stack<Character> s=new Stack<Character>(); Scanner sc=new Scanner(System.in); exep=sc.next(); while((token=exep.charAt(i++))!=‘=‘){ if(token>=‘a‘ && token<=‘z‘){ System.out.print(token+" "); }else{ switch(token){ case ‘+‘ : //省略掉的同时没写break;是因为,只要是小于或者等于的都会出栈,因此,继续执行下面语句 case ‘-‘ : while(!s.isEmpty() && s.peek()!=‘(‘){ System.out.print(s.pop()+" "); } s.push(token); break; case ‘*‘ : case ‘/‘ : while(!s.isEmpty() && s.peek()!=‘(‘ && s.peek()!=‘+‘ && s.peek()!=‘-‘){ System.out.print(s.pop()+" "); } s.push(token); break; case ‘(‘ : s.push(token); break; case ‘)‘ : while (!s.isEmpty() && s.peek()!=‘(‘){ System.out.print(s.pop()+" "); } s.pop(); break; case ‘^‘ : while (!s.isEmpty() && !(s.peek()==‘(‘ || s.peek()==‘^‘)){ System.out.print(s.pop()+" "); } s.push(token); break; } } } //最后检测,将剩余的全部出栈 while (!s.isEmpty()){ System.out.print(s.pop()+" "); } } }
二、后缀表达式转换为中缀表达式代码
首先,区别一下,这个后缀表达式转换为中缀表达式与前面不同,这里进行出入栈操作的是数字,而不是运算符。自己在网上找了很久,没发现有人写出这种转法的java代码,也许是没人放出来吧。于是,自己动手写了一个。思想与中缀表达式转换为后缀表达式有点不同。具体看代码吧!
首先,我的思想是,将一个表达式中的运算符取出并用一个数组存储,对于怎么自动加括号,通过判断下一个运算符优先级。
(假如: 有 6523+8*+3+* 我们很容易计算得到其中缀表达式为 ((3+2)*8+5+3)*6,所以,由第一个运算符 ”+“的下一个运算符 "*", 便可以知道,其 3+2 需要用括号括起来。其他方式也是,具体看代码。 )。最后,算法不是特别完美,欢迎指正!
package com.liyongdada.cn; import java.util.Scanner; import java.util.Stack; public class HouToZhong { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String expp;// 接收输入的表达式 String token; int i = 0; int ssLength = 0;// 记录运算符数组的大小 int charIndex = 0; // 用于记录已输出运算符的个数 Scanner sc = new Scanner(System.in); expp = sc.next(); //计算表达式中,有多少个运算符 for (int j = 0; j < expp.length(); j++) { if (!Character.isDigit(expp.charAt(j))) { ssLength += 1; } } //定义大小 char[] ss = new char[ssLength]; int sj = 0; //依次赋值 for (int j = 0; j < expp.length(); j++) { if (!Character.isDigit(expp.charAt(j))) { ss[sj++] = expp.charAt(j); } } //泛型为String类型,这可以避免每次复写掉 Stack<String> s = new Stack<String>(); String pop1, pop2;//用于接收每次取出的栈顶字符串 while (!(token = expp.substring(i, ++i)).equals("=")) { if (token.matches("[0-9]?")) { s.push(token); } else { // 只有jre1.7才能使用字符串作为switch中的值 switch (token.charAt(0)) { case ‘+‘: if (charIndex < ssLength - 1) { pop1 = s.pop(); pop2 = s.pop(); if (ss[charIndex + 1] == ‘*‘ || ss[charIndex + 1] == ‘/‘) { //调用自定义方法 s.push(mixExpp(pop2, pop1, "+")); } else s.push(pop2 + "+" + pop1); } else { System.out.println("执行错误!+!"); return; } charIndex++; break; case ‘-‘: if (charIndex < ssLength - 1) { pop1 = s.pop(); pop2 = s.pop(); if (!(ss[charIndex + 1] != ‘*‘ || ss[charIndex + 1] != ‘/‘)) { s.push(mixExpp(pop2, pop1, "-")); } else s.push(pop2 + "-" + pop1); } else { System.out.println("执行错误!-!"); return; } charIndex++; break; case ‘*‘: pop1 = s.pop(); pop2 = s.pop(); s.push(pop2 + "*" + pop1); charIndex++; break; case ‘/‘: pop1 = s.pop(); pop2 = s.pop(); s.push(pop1 + "/" + pop2); charIndex++; break; case ‘^‘: pop1 = s.pop(); pop2 = s.pop(); s.push(pop2 + "^" + pop1); charIndex++; break; } } } // 取出最后一个 System.out.println(s.pop()); } // 用于拼接括号的方法 public static String mixExpp(String one, String two, String fuhao) { String str = "(" + one + fuhao + two + ")"; return str; } }
以上是关于数据结构中缀表达式转后缀表达式以及后缀转中缀表达式的主要内容,如果未能解决你的问题,请参考以下文章