java解析字串表示式--逆波蘭表示式的計算
阿新 • • 發佈:2018-12-17
上回合我們講了如何將中綴表示式轉換成逆波蘭表示式,這回合我們講一講如何計算逆波蘭表示式。結合這一回合和上一回合,我們將能夠實現這樣一個功能:計算一箇中綴表示式的結果!話不多說,走起來!
問題來由:
讀入一個字串形式的四則運算表示式,輸出對應的計算結果。如讀入的是“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年提出了另一種表示表示式的方法。按此方法,每一運算子都置於其運算物件之後,故稱為字尾表示。
字尾表示式計算:
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),該演算法的計算非常簡單,同時不需要知道任何的計算優先順序。
到此,我們已經能夠實現將一箇中綴表示式轉換成字尾表示式(逆波蘭表示式),並計算出結果。