棧應用(中綴表達式轉後綴表達式並計算後綴表達式的值)

【0】README

0.1) 本文旨在總結 中綴表達式轉後綴表達式並計算後綴表達式的值 的步驟,並給出源代碼實現;
0.2) 本文中涉及到的源代碼均爲原創,是對中綴轉後綴和計算後綴的簡單實現,(旨在理清它的原理),故源代碼中 考慮的數字是一位整型數(由於若是是兩位數及以上的話,還涉及到字符串轉int類型,雖然,咱們沒有加入其功能,可是仍是定義了相關的函數,給出了接口的,朋友須要的話,能夠自行實現)、還有就是 運算符的話,只考慮到了 *、+、(、),一樣,若是朋友些須要的話,能夠自行增長case 語句 or if 語句添加上便可;
0.3) 須要注意的是,操做數operand 和 操做符(運算符)operator 只能用char 類型將它們區分開;在中綴轉後綴的過程當中,只能用char類型的空間來存儲它們的ASCII值(固然int空間也能夠,也是存儲它們的ASCII值);
0.4) 在計算後綴的過程當中,須要把數字字符串(如123,它的ASCII序列爲 49 50 51)轉爲int 類型或其餘數據類型,因此本文中的源代碼只處理 一位 整數的狀況;朋友須要的話,自行添加;
0.5) 對於寫算法代碼的感悟, 重在理清算法原理 or idea,不要把輸入輸出的各類狀況都考慮到, 那樣很累,很燒精力,影響學習進度;其實只要實現了其 簡單版本,實現複雜狀況 也不是那樣難;總之一句話,學習期間,咱們不追求完美,一切從簡,重在理解算法idea;
0.6) 題外話,曾經看到一位前輩說,棧有兩種實現方法——數組實現+鏈表實現, 說在工做中,棧的數組實現應用的比較多,鏈表實現基本不怎麼用,因此,你知道側重點在哪裏了;(固然能夠 看看 棧的鏈表實現 瞭解瞭解)
git


【1】中綴到後綴的轉換

1.1)此方法須要遵循幾個規則(Rule):github

  • R1)若是讀入操做數,則直接放入輸出字符串;
  • R2)若是讀入通常運算符如+-*/,則放入堆棧,可是放入堆棧以前必需要檢查棧頂,並肯定棧頂運算符的優先級比放入的運算符的優先級低;若是放入的優先級較低或二者相等的話,則須要將棧頂的運算符先放入輸出字符串, 而後再將剛讀入的運算符壓棧;
  • R3)若是讀入(,由於左括號優先級最高,所以放入棧中,可是注意,當左括號放入棧中後,則優先級最低;
  • R4)若是讀入),則將棧中運算符取出放入輸出字符串,直到取出(爲止,注意:()不輸出到輸出字符串;
  • R5)順序讀完表達式,若是棧中還有操做符,則彈出,並放入輸出字符串;

1.2)看個荔枝【 將中綴表達式:a + b * c + (d * e + f) * g 轉換爲 後綴表達式: a b c * + d e * f + g * + 】
咱們來看轉換步驟:
算法

  • step1)讀入a,a被輸出;讀入+, 因爲操做符棧空,故+進棧;讀入b,b被輸出;棧和輸出的狀態以下:
    這裏寫圖片描述
    數組

  • step2)讀入*,因爲棧頂+的優先級小於*,故*進棧;讀入c,c被輸出;棧和輸出的狀態以下:
    這裏寫圖片描述
  • **step3)讀入+,因爲棧頂*的優先級大於+,*出棧被送往輸出;有因爲棧頂+的優先級等於+,+出棧被送往輸出;棧和輸出的狀態以下:**
    這裏寫圖片描述
  • step4)讀入(,因爲(的優先級最高,故(進棧;讀入d,d被輸出;棧和輸出的狀態以下:
    這裏寫圖片描述
  • step5)讀入*,因爲(和)不會被輸出,故*進棧;讀入e,e被輸出;棧和輸出的狀態以下:
    這裏寫圖片描述
  • **step6)讀入+, 因爲棧頂*的優先級大於+,故*出棧被送往輸出;而後+進棧;讀入f,f被輸出;棧和輸出的狀態以下:**
    這裏寫圖片描述
  • step7)讀入),將棧中運算符出棧並被輸出,直到取出(爲止,而(和)不會被輸出;棧和輸出的狀態以下:
    這裏寫圖片描述
  • step8)讀入*, 因爲棧頂+的優先級小於*,故*進棧;讀入g,g被輸出;棧和輸出的狀態以下:
    這裏寫圖片描述
  • step9)讀完表達式後,棧中還有操做符,將它們出棧,並放入到輸出字符串;棧和輸出的狀態以下:
    這裏寫圖片描述
    ide

  • 中綴轉後綴的源代碼: https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter3/p54_infix_to_postfix
    這裏寫圖片描述
    函數


    【2】計算後綴表達式

    2.1)後綴表達式定義: 4.991.06 + 5.99 + 6.991.06 轉換爲後綴表達式爲: 4.99 1.06 * 5.99 + 6.99 1.06 * +;這種記法叫作 後綴 或者 逆波蘭 記法;post

2.2) 計算一個後綴表達式花費的時間是O(N);學習

2.3)計算後綴表達式規則(Rules):idea

  • R1) 若是是操做數,則放入棧中;
  • R2) 若是是操做符(運算符),則取出棧中兩個操做數,進行運算後,將結果放入棧中;
  • R3) 直到最後棧中只有一個元素,此元素就是計算結果;

2.4)看個荔枝(計算後綴表達式 1 2 3 * + 4 5 * 6 +7 * + )接口

  • 咱們看處理步驟:
  • step1)一、二、3進棧,結果以下:
    這裏寫圖片描述
  • **step2)下面讀到一個*, 因此二、3彈出, 將它們的積6壓棧,結果以下:**
    這裏寫圖片描述
  • step3)下面讀到一個+,因此一、6彈出,將它們的和7壓棧,結果以下:
    這裏寫圖片描述
  • step4)下面讀到 四、5 , 將它們壓棧,結果以下:
    這裏寫圖片描述
  • **step5)下面讀到一個*,因此四、5彈出,將它們的積20壓棧,結果以下:**
    這裏寫圖片描述
  • step6)下面讀到6,因此6壓棧,結果以下:
    這裏寫圖片描述
  • step7)下面讀到一個+,因此20、6彈出,將它們的和26壓棧,結果以下:
    這裏寫圖片描述
  • step8)下面讀到7,因此7壓棧,結果以下:
    這裏寫圖片描述
  • **step9)下面讀到一個*,因此2六、7彈出,將它們的積182壓棧,結果以下:**
    這裏寫圖片描述
  • step10)下面讀到一個+,因此七、182彈出,將它們的和189壓棧,結果以下:
    這裏寫圖片描述
  • step11)最後棧中就只有一個元素189了,因此結果就是189,並將其返回到主函數;

  • **計算後綴表達式(只考慮‘+’和 ‘*’) 的源代碼:**
    https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter3/p52_compute_postfix
  • Attention)當一個表達式以 後綴記號 給出時,沒有必要知道任何優先級規則, 這是一個明顯的優勢;
    這裏寫圖片描述

相關文章
相關標籤/搜索