数据结构中缀表达式转后缀表达式以及后缀转中缀表达式

来源:互联网 发布:达德网络 编辑:程序博客网 时间:2024/04/29 02:30

最近一直在看数据结构这本书,我相信,对于每个程序员来说,数据结构都尤为重要。为什么要学,可以看看这位博友的认识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 stubCharacter token;String exep;int i=0;//下面一句需要jre1.5Stack<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 stubString 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, "+"));} elses.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, "-"));} elses.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;}}


0 0
原创粉丝点击