1. 程式人生 > 其它 >字首中綴字尾表示式以及字尾表示式簡單計算的實現

字首中綴字尾表示式以及字尾表示式簡單計算的實現

7.5 字首,中綴,字尾表示式(逆波蘭表示式)

7.5.1 字首表示式(波蘭表示式)

  1. 字首表示式又稱波蘭表示式,字首表示式的運算子位於運算元之前

  2. 舉例說明:(3 + 4) X 5 - 6 對應的字首表示式就是 - X + 3 4 5 6

7.5.1.1 字首表示式的計算機求值

右至左掃描 表示式,遇到數字時,將數字壓入堆疊,遇到運算子時,彈出棧頂的兩個數,用運算子對他們左相應的計算(堆頂元素 和 此頂元素), 並將結果入棧;重複上述過程直到表示式最左端,最後運算得出的值即為表示式的結果

例如:(3+4)X5-6對應的字首表示式就是-X+3456,針對字首表示式求值步驟如下:

  1. 從右至左掃描

    ,將 6、5、4、3壓入堆疊

  2. 遇到+運算子,因此彈出3和4(3為棧頂元素,4為次頂元素,減肥操作時是先出來的數減去後出來的數),計算出3+4的值,得到7,在將7壓入棧

  3. 接下來就是X運算子,因此彈出7和5,計算出7X5=35,將35入棧

  4. 最後是-運算子,計算出35-6的值,即29,由此得出最終結果

7.5.2 中綴表示式

  1. 中綴表示式就是常見的預算表達式;如(3+4)X5-6

  2. 中綴表示式的求值是我們人最熟悉的,但是對計算機來說卻不會操作,(就是之前使用陣列棧進行計算的時候,要事先將運算子的優先順序錄入,以及每次讀到運算子的時候要先獲得它的優先順序進行比較)因此,在計算結果時,往往會將中綴表示式轉成其他表示式來操作(一般轉換成字尾表示式)

7.5.3 字尾表示式(逆波蘭表示式)

  1. 字尾表示式又稱逆波蘭表示式,與字首表示式相似,只是運算子位於運算元之後

  2. 中綴表示式舉例說明:(3+4)X5-6對應的字尾表示式就是3 4 + 5 X 6 -

7.5.3.1 字尾表示式的計算機求值

從左至右掃描表示式,遇到數字時,將數字壓入堆疊,遇到運算子時,彈出棧頂的兩個數,用運算子對它們做相應的計算(此頂元素和棧頂元素),並將結果入棧:重複上述過程直到表示式最右端,最後運算得出的值即為表示式的結果

例如:(3+4)X5-6對應的字尾表示式就是-X+3456,針對字首表示式求值步驟如下:

  1. 從左至右掃描,將 3 和 4 壓入堆疊

  2. 遇到 + 運算子,因此彈出 4 和 3 (4為棧頂元素,3 為次頂元素),計算出 3 + 4 的值,得 7, 再將 7 入棧

  3. 將 5 入棧

  4. 接下來是 X 運算子,因此彈出 5 和 7,計算出 7 X 5 = 35, 將 35 入棧

  5. 將 6 入棧

  6. 最後是 - 運算子,計算出 35 - 6(減法運算或者除法運算的時候,字尾表示式是 次頂元素 減去或除以 堆頂元素) 的值,即 29 ,由此得出最終結果

7.6 逆波蘭計算器

我們完成一個逆波蘭表示式,要求完成如下任務:

  1. 輸入一個逆波蘭表示式(字尾表示式),使用棧(stack用系統提供的棧實現),計算其結果

  2. 支援小括號和多位數整數,以為這裡我們主要講的是資料結構,依次計算器進行簡化,支支援對整數的計算。

中綴表示式轉換成字尾表示式,不會的可以看看大佬的

 1 package stack;
 2  3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.Stack;
 6  7 public class PolandNotation {
 8     public static void main(String[] args) {
 9         // 先定義 逆波蘭表示式
10         // (3+4)X5-6 => 3 4 + 5 x 6 -
11         //  4 * 5 - 8 + 60 + 8 / 2 => 4 5 * 8 - 60 + 8 2 / +
12         // 說明為了方便,逆波蘭表示式 的數字和符號使用空格隔開
13         // String expression = "30 4 + 5 * 6 -";
14         String expression = "4 5 * 8 - 60 + 8 2 / +";
15         // 思路:
16         // 1. 先將“3 4 + 5 x 6 -”放進ArrayList中(省的一個一個掃描)
17         // 2. 將 ArrayList 傳遞給一個方法,遍歷 Array List 配合棧完成計算
18 19         List<String> list = getListString(expression);
20         System.out.println("rpnList="+list);
21 22         int res = calculate(list);
23         System.out.println("(3+4)X 5-6"+"計算的結果是:" + res);
24     }
25 26     // 將一個逆波蘭表示式,依次將資料和運算子 放入ArrayList
27     public static List<String> getListString(String expression){
28         // 將 expression 分割
29         String[] split = expression.split(" ");
30         List<String> list = new ArrayList<String>();
31         for (String ele : split){
32             list.add(ele);
33         }
34         return list;
35     }
36     // 完成對逆波蘭表示式的運算
37     /*
38     1. 從左至右掃描,將 3 和 4 壓入堆疊
39     2. 遇到 + 運算子,因此彈出 4 和 3 (4為棧頂元素,3 為次頂元素),計算出 3 + 4 的值,得 7, 再將 7 入棧
40     3. 將 5 入棧
41     4. 接下來是 X 運算子,因此彈出 5 和 7,計算出 7 X 5 = 35, 將 35 入棧
42     5. 將 6 入棧
43     6. 最後是 - 運算子,計算出 35 - 6(減法運算或者除法運算的時候,字尾表示式是 次頂元素  減去或除以  堆頂元素) 的值,即 29 ,由此得出最終結果
44      */
45 46     public static int calculate(List<String> ls){
47         // 建立一個棧,只需要一個棧即可
48         Stack<String> stack = new Stack<>();
49         // 遍歷 ls
50         for(String item : ls){
51             // 這裡使用一個正則表示式取出數
52             if (item.matches("\\d+")){
53                 // 匹配的是多位數
54                 stack.push(item);
55             } else {
56                 // pop 出兩個數並運算,在入棧
57                 int num2 = Integer.parseInt(stack.pop());
58                 int num1 = Integer.parseInt(stack.pop());
59                 int res = 0;
60                 if (item.equals("+")){
61                     res = num1 + num2;
62                 } else if (item.equals("-")){
63                     res = num1 - num2;
64                 } else  if (item.equals("*")){
65                     res = num1 * num2;
66                 } else if (item.equals("/")){
67                     res = num1 / num2;
68                 } else {
69                     throw  new RuntimeException("符號有問題");
70                 }
71                 // 把res入棧,入棧的時候要將res轉換成字元,因為我們的棧是字串型別的
72                 stack.push(res+"");
73             }
74         }
75         // 最後留在stack的資料是運算結果
76         return Integer.parseInt(stack.pop());
77     }
78 }