1. 程式人生 > >java 實現 中序表示式轉後序表示式(逆波蘭式) 以及 後序表示式求值

java 實現 中序表示式轉後序表示式(逆波蘭式) 以及 後序表示式求值

第一次寫部落格,還是個學生,沒有什麼經驗,只是單純的記錄下自己實現一個問題的方法與思想,如有錯誤之處,請各路大神批評指出。

大概思想:跟參考部落格的思想差不多,單程式碼完全自己思考,實現過程有較多的if..else語句 看起來可能會有點暈。各處都有註釋有不懂的可以私信我。

這個程式還有一個好處是在於求後續表示式的時候,如果指定序列有其他字元(可能誤輸入)也可以生成對應的後續表示式,還會提醒哪個位置是哪個字元有誤。比如指定序列為 String str = "3¥+9*7+(2*1】+7)*2^"; 程式執行結果如下:

執行截圖

完整程式碼如下:

package reversePolish;

import java.util.*;


public class ReversePolish{
	
	public static void main(String args[]){
		String str = "3+9*7+(2*1+7)*2";
		System.out.println(reversePolish(str));
		System.out.println(sumReversePolish(reversePolish(str)));
	}
	
	public static String reversePolish(String str){
		//String[] strArray = str.split("");
		String str1;
		char[] strArray = str.toCharArray();
		String[] operator = {"+","-","/","*","(",")"};
		List<String> list = Arrays.asList(operator);
		LinkedList<String> list1 = new LinkedList<String>();  //輸出棧
		LinkedList<String> list2 = new LinkedList<String>();   //操作符棧
		for(int i = 0;i < strArray.length; i++){
			/*該部分為查bug過程 ,一步一步看輸出是否一致
			 if(i == 14) {
				Iterator<String> it1 = list1.iterator();
				Iterator<String> it2 = list2.iterator();
				while(it1.hasNext()) {
					System.out.print(it1.next() + " ,");
				}
				System.out.println();
				while(it2.hasNext()) {
					System.out.print(it2.next() + " ,");
				}
				System.out.println();
				//System.exit(-1);
			}*/
			if(Character.isDigit(strArray[i]) || Character.isLetter(strArray[i])){     //如果是運算元或者字母直接輸出
				list1.add(Character.toString(strArray[i]));
			}else if(list.contains(Character.toString(strArray[i]))){
				if(list2.size() == 0){
					list2.addFirst(Character.toString(strArray[i]));                 //操作符入棧
				}else {
					if(Character.toString(strArray[i]).equals("(")){
						list2.addFirst(Character.toString(strArray[i]));                 //操作符入棧
					}
					else if(Character.toString(strArray[i]).equals(")")){
						String[] strA = list2.toArray(new String[0]);
						for(int j = 0;j < strA.length;j++) {
							do{
								if(list2.size() == 0) {
									//這裡寫不寫都行,因為有括號不可能在第一個位置
								}else {
									if(strA[j].equals("(")){
										list2.pollFirst();
										j = strA.length - 1;
									}else{
										list1.add(list2.pollFirst());
									}
								}
							}while(strA[j].equals("("));
						}
					}
					//如果是加號或者減號,則除了遇到左括號,全部要出棧
					else if(Character.toString(strArray[i]).equals("+") || Character.toString(strArray[i]).equals("-")){
						String[] strB = list2.toArray(new String[0]); //要對操作符棧進行操作,所以不能使用Iterator進行操作(iterator操作的時候不能進行list的改動)
						if(strB[0].equals("(")){
							list2.addFirst(Character.toString(strArray[i]));
						}else {
							for(int k = 0;k < strB.length;k++) {
								if(strB[k].equals("(")) {
									list2.addFirst(Character.toString(strArray[i]));
									k = strB.length - 1;  //遇到左括號直接入棧,跳出迴圈,下面類似
								}else {
									do{
										if(list2.size() == 0) {
											list2.addFirst(Character.toString(strArray[i]));
										}else {		
											list1.add(list2.pollFirst());
										}
									}while(strB[k].equals("("));
								}
							}
						}
						if(list2.size() == 0){  //因為棧裡面的資料都出棧了,所以剛掃描的符號要進棧,前提是沒有左括號
							list2.addFirst(Character.toString(strArray[i]));
						}
					}
					//如果是乘號或者除號,棧頂元素為+或者-或者(進棧,*或者、出棧
					else if(Character.toString(strArray[i]).equals("*") || Character.toString(strArray[i]).equals("/")){	
						String[] strC = list2.toArray(new String[0]);	
						if(strC[0].equals("(")) {
							list2.addFirst(Character.toString(strArray[i]));
						}else {
							for(int l = 0;l < strC.length;l++) {
								if(strC[l].equals("(")) {
									list2.addFirst(Character.toString(strArray[i]));
									l = strC.length - 1;
								}else {
									do{
										if(list2.size() == 0){
											list2.addFirst(Character.toString(strArray[i]));
										}else {
											if(strC[l].equals("*") || strC[l].equals("/")){
												list1.add(list2.pollFirst());
											}else if(strC[l].equals("+") || strC[l].equals("-")){
												list2.addFirst(Character.toString(strArray[i]));
											}else {}
										}
									}while(strC[l].equals("("));
								}
							}
						}
						if(list2.size() == 0){
							list2.addFirst(Character.toString(strArray[i]));
						}
					}
				}
			}
			else {
				System.out.println("輸入字串中的第個" + i + "符號 " + strArray[i] + "無法識別,請核對!");
			}
		}
		//字串掃描完畢,把操作符棧剩下的操作符依次取出到輸出棧
		int len = list2.size();
		for(int p = 0;p < len;p++){
			list1.add(list2.pollFirst());
		}
		String[] strOutput = list1.toArray(new String[0]);  
		StringBuffer sb = new StringBuffer();
		for(int i = 0; i < strOutput.length; i++){
		 sb. append(strOutput[i]);
		}
		str1 = sb.toString();
		
		return str1;
	}
	
	
	//後序表示式求值,要求中序序列只能有數字不能有字母
	public static int sumReversePolish(String str){          
		//char[] strArray = str.toCharArray();
		String[] strArray = str.split("");
		LinkedList<Integer> list1 = new LinkedList<Integer>(); //存運算元
		int a = 0,b = 0,sum = 0;
		for (int i = 0; i < strArray.length; i++) {
			 if(strArray[i].equals("+") || strArray[i].equals("-") || strArray[i].equals("*") || strArray[i].equals("/")){
				sum = 0;
				a = list1.pollFirst();  //獲取第一個數
				b = list1.pollFirst();  //獲取第二個數
				switch(strArray[i]) {
					case "+": sum = a + b; list1.addFirst(sum); break;
					case "-": sum = a - b; list1.addFirst(sum); break;
					case "*": sum = a * b; list1.addFirst(sum); break;
					case "/": sum = a / b; list1.addFirst(sum); break;
				}
			}else {				
					list1.addFirst(Integer.valueOf(strArray[i]).intValue()); //數字的話直接加入列表
			}
		}
		return sum;
	}
}

如若轉載請註明出處,謝謝。