中綴表達式
- 中綴表達式是一個通用的算術或邏輯公式表示方法, 操作符是以中綴形式處於操作數的中間(例:3 + 4),中綴表達式是人們常用的算術表示方法。中綴記法中括號是必需的。計算過程中必須用括號將操作符和對應的操作數括起來,用於指示運算的次序。
- 8+4-62用後綴表達式表示爲:8 4+6 2-
- 2*(3+5)+7/1-4用後綴表達式表示爲:235+*71/+4-
前綴表達式
- 前綴表達式是一種沒有括號的算術表達式,與中綴表達式不同的是,其將運算符寫在前面,操作數寫在後面。爲紀念其發明者波蘭數學家Jan Lukasiewicz,前綴表達式也稱爲“波蘭式”。例如,- 1 + 2 3,它等價於1-(2+3)。
- 作用:前綴表達式是一種十分有用的表達式,將中綴表達式轉換爲前綴表達式後,就可以只依靠出棧、入棧兩種簡單操作完全解決中綴表達式的全部運算。
後綴表達式
- 一個表達式E的後綴形式可以如下定義:
- 如果E是一個變量或常量,則E的後綴式是E本身。
- 如果E是E1 op E2形式的表達式,這裏op是任何二元操作符,則E的後綴式爲E1’E2’ op,這裏E1’和E2’分別爲E1和E2的後綴式。
- 如果E是(E1)形式的表達式,則E1的後綴式就是E的後綴式。
- 如:我們平時寫a+b,這是中綴表達式,寫成後綴表達式就是:ab+
- 作用:
實現逆波蘭式的算法,難度並不大,但爲什麼要將看似簡單的中序表達式轉換爲複雜的逆波蘭式?原因就在於這個簡單是相對人類的思維結構來說的,對計算機而言中序表達式是非常複雜的結構。相對的,逆波蘭式在計算機看來卻是比較簡單易懂的結構。因爲計算機普遍採用的內存結構是棧式結構,它執行先進後出的順序。
中綴表達式轉後綴表達式:
-
示例說明:
將中綴表達式“1+((2+3)×4)-5”轉換爲後綴表達式的過程如下:
因此結果爲 :“1 2 3 + 4 × + 5 –” -
示例代碼:
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class Calculator {
public static int getComputingResult(String expression){
return 0;
}
private static String transferNifixExpressionToPostfixExpression(String nifixExpression){
//存儲表達式的中間結果
Stack<Character> expStack = new Stack<>();
//存儲運算符
Stack<Character> opStack = new Stack<>();
//存儲運算符和優先值鍵值對
Map<Character, Integer> ops = new HashMap<>();
// ops.put('(', 0);
ops.put('+', 1);
ops.put('-', 1);
ops.put('*', 2);
ops.put('/', 2);
//把中綴表達式字符串轉換爲字符數組
char [] chars = new char[nifixExpression.length()];
nifixExpression.getChars(0, nifixExpression.length(), chars, 0);
//遍歷數組,處理每一個表達式中的字符
for(int i = 0;i < chars.length;i ++){
if(chars[i] >= 48 && chars[i] <= 57){
expStack.push(chars[i]);
}else {
if(opStack.isEmpty() || opStack.peek() == '('){
opStack.push(chars[i]);
}else {
if(chars[i] == '('){
opStack.push(chars[i]);
}else if(chars[i] == ')'){
while (opStack.peek() != '('){
expStack.push(opStack.pop());
}
opStack.pop();
}else {
while (ops.get(chars[i]) <= ops.get(opStack.peek())){
expStack.push(opStack.pop());
if(opStack.size() == 0)break;
}
opStack.push(chars[i]);
}
}
}
}
opStack.forEach(character -> {
expStack.push(character);
});
StringBuilder stringBuilder = new StringBuilder("");
expStack.forEach(character -> {
stringBuilder.append(character);
});
return stringBuilder.toString();
}
public static void main(String[] args) {
System.out.println(transferNifixExpressionToPostfixExpression("1+((2+3)*4)-5"));
}
}
- 輸出:
123+4*+5-
- 注意,如果想把"運算符棧爲空或者棧頂元素爲’('把運算符直接壓入棧" 的條件改爲"運算符棧爲空把運算符直接壓入棧",可以把’('運算符的優先級設置爲最低。