這裏所謂的前綴,中綴,後綴是根據操做符的位置來定的,若是操做符在操做數前面,則稱爲前綴表達式,例如「- + 1 × + 2 3 4 5」;若是操做符在操做數之間,則稱爲中綴表達式,例如java
「1+((2+3)×4)-5」;若是操做符在操做數後面,則稱爲後綴表達式,例如「1 2 3 + 4 × + 5 -」。算法
雖然中綴表達式符合人類的平常思惟習慣,可是計算機在存儲中綴表達式時,須要使用樹這種數據結構,若是表達式過於複雜,那麼樹的高度會變得很高,大大增長了時間複雜度和空間複雜度。若是轉換成線性結構,那麼效率將變得高不少,因此須要將中綴表達式先轉換成前綴或者後綴表達式,而後依靠棧這種線性數據結構來進行計算。數據結構
前綴表達式又叫波蘭表達式,後綴表達式又叫逆波蘭表達式。前綴表達式基本沒有在商業計算機中使用過,因此現實中用的更多的是後綴表達式。spa
中綴表達式爲:1+(2-3)*4+4/2code
對應後綴表達式爲:1 2 3 - 4* + 4 2 / +blog
如何將一箇中綴表達式轉化爲後綴表達式?咱們須要藉助棧的力量,用它來存放運算符。算法流程以下:字符串
首先將各類運算符(包括括號)的優先級排列以下(數字越大,優先級越高):it
1:(io
2:+ -ast
3:* /
4:)
對輸入的中綴表達式從左到右遍歷:
1)若是遇到數字,直接添加到後綴表達式末尾;
2)若是遇到運算符+、-、*、/:
先判斷棧是否爲空。如果,則直接將此運算符壓入棧。若不是,則查看當前棧頂元素。若棧頂元素優先級大於或等於此操做符級別,則彈出棧頂元素,將棧頂元素添加到後綴表達式中,並繼續進行上述判斷。若是不知足上述判斷或者棧爲空,將這個運算符入棧。要注意的是,通過上述步驟,這個運算符最終必定會入棧。
3)若是遇到括號:
若是是左括號,直接入棧。若是是右括號,彈出棧中第一個左括號前全部的操做符,並將左括號彈出。(右括號別入棧)。
4)字符串遍歷結束後,若是棧不爲空,則彈出棧中全部元素,將它們添加到後綴表達式的末尾,直到棧爲空。
也稱爲逆波蘭表達式
package com.cnblogs.mufasa.Main_last; import org.junit.Test; import java.util.Scanner; import java.util.Stack; public class Main { public static void Solution(String str){ Stack<Float> stack=new Stack<>(); String[] strs=str.split(" "); for(int i=0;i<strs.length;i++){ if(strs[i].matches("([0-9]+)\\.?([0-9]*)")){//是一個數字,多是多位的 stack.add(Float.valueOf(strs[i])); }else { float num1=stack.pop(); float num2=stack.pop(); stack.add(dealCalcu(num1,num2,strs[i])); } } System.out.print(stack.pop()); } private static float dealCalcu(float num1,float num2,String str){ switch (str){ case "+":return num1+num2; case "-":return num1-num2; case "*":return num1*num2; case "×":return num1*num2; case "X":return num1*num2; case "/":return num1/num2; default:throw new UnsupportedOperationException("非法運算符"); } } @Test public void LastCalcu (){ String str="1.11 2 3 + 4 * + 5 -"; Solution(str); } public static void main(String[] args) { Scanner sc=new Scanner(System.in); Solution(sc.nextLine()); } } /* 1 2 3 + 4 * + 5 - */