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

最近一直在看数据结构这本书,我相信,对于每个程序员来说,数据结构都尤为重要。为什么要学,可以看看这位博友的认识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;
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值