前綴、中綴、後綴表達式(逆波蘭表達式分析與實現)

一、前綴表達式

從右至左掃描表達式:

1、遇到數字時,將數字壓入堆棧;

2、遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算(棧項元素和次頂元素),並將結果入棧;

3、重複上述過程直到表達式最左端,最後運算得出的值即爲表達式的結果。

【舉例】
( 3 +4 ) * 5 - 6 對應的前綴表達式 - * + 3 4 5 6
步驟如下:
(1)、從右至左掃描,將6、5、4、3壓入堆棧;

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

(3)、接下來是運算符,因此彈出7和5,計算出75=35,將35入棧;

(4)、最後是-運算符,計算出35-6的值,即29,即爲最終結果。

二、中綴表達式

1、中綴表達式就是常見的運算表達式,如(3+4)*5-6;

2、 中綴表達式的求值是我們人最熟悉的,但是對計算機來說卻不好操作(上一個博客寫過代碼),因此,在計算結果時,往往會將中綴表達式轉成其它表達式來操作。(常見的操作是:中綴表達式轉後綴表達式)。

三、後綴表達式

1、後綴表達式又稱逆波蘭表達式,運算符位於操作數之後。

2、舉例說明: ( 3 + 4 ) * 5 - 6 對應的後綴表達式 3 4 + 5 * 6 -

3、一些轉後綴表達式的例子:

① a + b → a b +

② a + ( b - c ) → a b c - +

③ a + d * ( b - c ) → a d b c - * +

④ a = 1 + 3 → a 1 3 + =

⑤ a + ( b - c ) * d → a b c - d * +

那麼如何實現逆波蘭表達式呢?

從左至右掃描表達式:

1、遇到數字時,將數字壓入堆棧;

2、遇到運算符時,彈出棧頂的兩個數,用運算符對它們做相應的計算(次項元素和棧項元素),並將結果入棧;

3、重複上述過程直到表達式最右,最後運算得出的值即爲表達式的結果。

【舉例】

( 3 + 4 ) * 5 - 6 對應的前綴表達式 3 4 + 5 * 6 -
步驟如下:
(1)、從左至右掃描,將3和4壓入堆棧;

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

(3)、將5入棧;

(4)、 接下來是運算符,因此彈出5和7,計算出75=35,將35入棧;

(5)、將6入棧;

(6)、 最後是-運算符,計算出35-6的值, 即29,即爲最終結果。

具體代碼實現如下:

package com.ycx.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class PolandNotation {
    public static void main(String[] args) {

        //先定義一個逆波蘭表達式:(3+4)*5-6  =>  3 4 + 5 * 6 -
        //測試
        // 4 * 5 - 8 + 60 + 8 / 2=> 4 5 * 8 - 60 + 8 2 /
        //爲了方便,逆波蘭表達式的數字和符號使用空格隔開


         String expression = "30 4 + 5 * 6 -";

        /*
            思路:
               1、將"3 4 + 5 * 6 -" 放到ArrayList中
               2、將ArrayList傳遞給一個方法,遍歷ArrayList,配合棧完成計算
         */

        List<String> list1 = getListString(expression);//放在List中方便取數,如果用index索引 需要一個一個的掃描,比較麻煩
        System.out.println("list1 =" + list1);

        int result1 = calculate(list1);
        System.out.println("計算結果是:"+ result1);
    }

    //將一個逆波蘭表達式,依次將數據和運算符 放到ArrayList中
    public static List<String> getListString(String expression){
        //將expression用空格分割
        String[] split = expression.split(" ");
        List<String> list = new ArrayList<String>();
        for (String ele : split){ //對split進行for循環 每循環一次就取出波蘭表達式中的一個元素
            list.add(ele);
        }
        return list;
    }

    /*
       完成逆波蘭表達式的步驟:
      1) 從左至右掃描,將3和4壓入堆棧;
      2) 遇到+運算符, 因此彈出4和3 (4爲棧頂元素,3爲次頂元素),計算出3+4的值,得7,再將7入棧;
      3) 將5入棧;
      4) 接下來是X運算符,因此彈出5和7,計算出7X5=35,將35入棧;
      5) 將6入棧;
      6) 最後是-運算符,計算出35-6的值, 即29,由此得出最終結果
    */

    public  static int calculate(List<String> list2){
        //創建棧
        Stack<String> stack = new Stack<String>();
        //遍歷list2
        for (String ele1:list2){
            if(ele1.matches("\\d+")){ //正則表達式:匹配多位數
                //如果是數就入棧
                stack.push(ele1);
            }else {   //如果是字符 就pop出兩個數 進行運算
                int num1 = Integer.parseInt(stack.pop()); //stack.pop() 出來的是字符 需要轉化成數字
                int num2 = Integer.parseInt(stack.pop());//num2 比 num1 後 pop出 所以注意減法和除法時的順序
                int result = 0;
                if(ele1.equals("+")){
                    result = num1 + num2;
                }else if(ele1.equals("-")){
                    result = num2 - num1;
                }else if(ele1.equals("*")){
                    result = num1 * num2;
                }else if(ele1.equals("/")){
                    result = num2 / num1;
                }else {
                    throw  new RuntimeException("運算符有誤");
                }
                //結果入棧
                stack.push(result+"");//整數轉化爲字符串
            }
        }
        //最後留在stack中的是運算結果
        return Integer.parseInt(stack.pop());
    }
}


運行結果如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章