1. 程式人生 > >java解析字串表示式--逆波蘭表示式的計算

java解析字串表示式--逆波蘭表示式的計算

上回合我們講了如何將中綴表示式轉換成逆波蘭表示式,這回合我們講一講如何計算逆波蘭表示式。結合這一回合和上一回合,我們將能夠實現這樣一個功能:計算一箇中綴表示式的結果!話不多說,走起來!

問題來由:

讀入一個字串形式的四則運算表示式,輸出對應的計算結果。如讀入的是“6 * ( 5 + ( 2 + 3) * 8 + 3)”,那麼解析後的輸出結果應為288。

思路:

一般的計算過程是這樣的,首先計算優先順序最高的小括號裡面的內容,即“( 5 + ( 2 + 3) * 8 + 3)”, 將“2 + 3”的計算結果並存為A,接著用計算“A*8”,並存為B 計算“5+B+3”,結果存為C 最後計算“6*C”,計算完畢 我們可以將這種操作順序書寫如下:

6 5 2 3 + 8 * + 3 + *

這個記法就是逆波蘭(reverse Polish)表示式,其求值過程恰好就是上面所描述的過程。逆波蘭表示式又叫做字尾(postfix)表示式。在通常的表示式中,運算子總是置於與之相關的兩個運算物件之間,所以,這種表示法也稱為中綴表示。波蘭邏輯學家 J.Lukasiewicz於1929年提出了另一種表示表示式的方法。按此方法,每一運算子都置於其運算物件之後,故稱為字尾表示。

字尾表示式計算:

     image

java程式碼如下:

package qiuzhitest;

public class CountReversePolishNotation {

	//計算逆波蘭表示式,這裡只考慮了運算元為個位的,不考慮運算元大於兩位及以上的,另外負數和小數均不考慮
	public static int countNotation(String notation){
		//新建一個堆,用來儲存非運算子的字元
		SequenceStack<String> stack=new SequenceStack<String>();
		//將字串轉換成字元陣列
		char[] arr=notation.toCharArray();
		//迴圈判斷字元陣列中的所有字元
		for(int i=0;i<arr.length;i++){
			char c=arr[i];
			//如果字元是0-9的,則壓入棧
			if(c>='0'&&c<='9'){
				stack.push(c+"");
			}else{//否則的話彈出兩個元素,對當前字元進行判斷,做相應的處理,並將處理的結果壓入棧中
				int a=Integer.parseInt(stack.pop());
				int b=Integer.parseInt(stack.pop());
				if(c=='+'){
					stack.push((a+b)+"");
				}else if(c=='-'){
					stack.push((a-b)+"");
				}else if(c=='*'){
					stack.push((a*b)+"");
				}else{
					//如果除數為0則丟擲異常
					if(b==0){
						throw new RuntimeException("除數為0");
					}
					stack.push((a/b)+"");
				}
				
			}
		}
		//棧中的最後一個元素就是計算後的結果
		int total=Integer.parseInt(stack.pop());
		
		return total;
	}
	public static void main(String[] args){
		System.out.println(countNotation("6523+8*+3+*"));
	}
}

演算法分析:

計算一個字尾表示式話費的時間是O(N),該演算法的計算非常簡單,同時不需要知道任何的計算優先順序。

到此,我們已經能夠實現將一箇中綴表示式轉換成字尾表示式(逆波蘭表示式),並計算出結果。