1. 程式人生 > >【軟考】字首、中綴、字尾表示式

【軟考】字首、中綴、字尾表示式

關鍵字:概念, 字首表示式, 字首記法, 中綴表示式, 中綴記法, 波蘭式, 字尾表示式, 字尾記法, 逆波蘭式


它們都是對錶達式的記法,因此也被稱為字首記法、中綴記法和字尾記法。它們之間的區別在於運算子相對與運算元的位置不同:字首表示式的運算子位於與其相關的運算元之前;中綴和字尾同理。

舉例:
(3 + 4) × 5 - 6 就是中綴表示式
- × + 3 4 5 6 字首表示式
3 4 + 5 × 6 - 字尾表示式

中綴表示式(中綴記法)
中綴表示式是一種通用的算術或邏輯公式表示方法,操作符以中綴形式處於運算元的中間。中綴表示式是人們常用的算術表示方法。
雖然人的大腦很容易理解與分析中綴表示式,但對計算機來說中綴表示式卻是很複雜的,因此計算表示式的值時,通常需要先將中綴表示式轉換為字首或字尾表示式,然後再進行求值。對計算機來說,計算字首或字尾表示式的值非常簡單。

字首表示式(字首記法、波蘭式)

字首表示式的運算子位於運算元之前。

字首表示式的計算機求值:
從右至左掃描表示式,遇到數字時,將數字壓入堆疊,遇到運算子時,彈出棧頂的兩個數,用運算子對它們做相應的計算(棧頂元素 op 次頂元素),並將結果入棧;重複上述過程直到表示式最左端,最後運算得出的值即為表示式的結果。
例如字首表示式“- × + 3 4 5 6”:
(1) 從右至左掃描,將6、5、4、3壓入堆疊;
(2) 遇到+運算子,因此彈出3和4(3為棧頂元素,4為次頂元素,注意與字尾表示式做比較),計算出3+4的值,得7,再將7入棧;
(3) 接下來是×運算子,因此彈出7和5,計算出7×5=35,將35入棧;
(4) 最後是-運算子,計算出35-6的值,即29,由此得出最終結果。
可以看出,用計算機計算字首表示式的值是很容易的。

將中綴表示式轉換為字首表示式:

遵循以下步驟:
(1) 初始化兩個棧:運算子棧S1和儲存中間結果的棧S2;
(2) 從右至左掃描中綴表示式;
(3) 遇到運算元時,將其壓入S2;
(4) 遇到運算子時,比較其與S1棧頂運算子的優先順序:
(4-1) 如果S1為空,或棧頂運算子為右括號“)”,則直接將此運算子入棧;
(4-2) 否則,若優先順序比棧頂運算子的較高或相等,也將運算子壓入S1;
(4-3) 否則,將S1棧頂的運算子彈出並壓入到S2中,再次轉到(4-1)與S1中新的棧頂運算子相比較;
(5) 遇到括號時:
(5-1) 如果是右括號“)”,則直接壓入S1;
(5-2) 如果是左括號“(”,則依次彈出S1棧頂的運算子,並壓入S2,直到遇到右括號為止,此時將這一對括號丟棄;
(6) 重複步驟(2)至(5),直到表示式的最左邊;
(7) 將S1中剩餘的運算子依次彈出並壓入S2;
(8) 依次彈出S2中的元素並輸出,結果即為中綴表示式對應的字首表示式。
例如,將中綴表示式“1+((2+3)×4)-5”轉換為字首表示式的過程如下:
掃描到的元素 S2(棧底->棧頂) S1 (棧底->棧頂) 說明
5 5 數字,直接入棧
- 5 - S1為空,運算子直接入棧
) 5 - ) 右括號直接入棧
4 5 4 - ) 數字直接入棧
× 5 4 - ) × S1棧頂是右括號,直接入棧
) 5 4 - ) × ) 右括號直接入棧
3 5 4 3 - ) × ) 數字
+ 5 4 3 - ) × ) + S1棧頂是右括號,直接入棧
2 5 4 3 2 - ) × ) + 數字
( 5 4 3 2 + - ) × 左括號,彈出運算子直至遇到右括號
( 5 4 3 2 + × - 同上
+ 5 4 3 2 + × - + 優先順序與-相同,入棧
1 5 4 3 2 + × 1 - + 數字
到達最左端 5 4 3 2 + × 1 + - S1中剩餘的運算子
因此結果為“- + 1 × + 2 3 4 5”。

字尾表示式(字尾記法、逆波蘭式)
字尾表示式與字首表示式類似,只是運算子位於運算元之後。

字尾表示式的計算機求值:
與字首表示式類似,只是順序是從左至右:
從左至右掃描表示式,遇到數字時,將數字壓入堆疊,遇到運算子時,彈出棧頂的兩個數,用運算子對它們做相應的計算(次頂元素 op 棧頂元素),並將結果入棧;重複上述過程直到表示式最右端,最後運算得出的值即為表示式的結果。
例如字尾表示式“3 4 + 5 × 6 -”:
(1) 從左至右掃描,將3和4壓入堆疊;
(2) 遇到+運算子,因此彈出4和3(4為棧頂元素,3為次頂元素,注意與字首表示式做比較),計算出3+4的值,得7,再將7入棧;
(3) 將5入棧;
(4) 接下來是×運算子,因此彈出5和7,計算出7×5=35,將35入棧;
(5) 將6入棧;
(6) 最後是-運算子,計算出35-6的值,即29,由此得出最終結果。

將中綴表示式轉換為字尾表示式:
與轉換為字首表示式相似,遵循以下步驟:
(1) 初始化兩個棧:運算子棧S1和儲存中間結果的棧S2;
(2) 從左至右掃描中綴表示式;
(3) 遇到運算元時,將其壓入S2;
(4) 遇到運算子時,比較其與S1棧頂運算子的優先順序:
(4-1) 如果S1為空,或棧頂運算子為左括號“(”,則直接將此運算子入棧;
(4-2) 否則,若優先順序比棧頂運算子的高,也將運算子壓入S1(注意轉換為字首表示式時是優先順序較高或相同,而這裡則不包括相同的情況);
(4-3) 否則,將S1棧頂的運算子彈出並壓入到S2中,再次轉到(4-1)與S1中新的棧頂運算子相比較;
(5) 遇到括號時:
(5-1) 如果是左括號“(”,則直接壓入S1;
(5-2) 如果是右括號“)”,則依次彈出S1棧頂的運算子,並壓入S2,直到遇到左括號為止,此時將這一對括號丟棄;
(6) 重複步驟(2)至(5),直到表示式的最右邊;
(7) 將S1中剩餘的運算子依次彈出並壓入S2;
(8) 依次彈出S2中的元素並輸出,結果的逆序即為中綴表示式對應的字尾表示式(轉換為字首表示式時不用逆序)。

例如,將中綴表示式“1+((2+3)×4)-5”轉換為字尾表示式的過程如下:
掃描到的元素 S2(棧底->棧頂) S1 (棧底->棧頂) 說明
1 1 數字,直接入棧
+ 1 + S1為空,運算子直接入棧
( 1 + ( 左括號,直接入棧
( 1 + ( ( 同上
2 1 2 + ( ( 數字
+ 1 2 + ( ( + S1棧頂為左括號,運算子直接入棧
3 1 2 3 + ( ( + 數字
) 1 2 3 + + ( 右括號,彈出運算子直至遇到左括號
× 1 2 3 + + ( × S1棧頂為左括號,運算子直接入棧
4 1 2 3 + 4 + ( × 數字
) 1 2 3 + 4 × + 右括號,彈出運算子直至遇到左括號
- 1 2 3 + 4 × + - -與+優先順序相同,因此彈出+,再壓入-
5 1 2 3 + 4 × + 5 - 數字
到達最右端 1 2 3 + 4 × + 5 - S1中剩餘的運算子

因此結果為“1 2 3 + 4 × + 5 -”(注意需要逆序輸出)。

編寫Java程式將一箇中綴表示式轉換為字首表示式和字尾表示式,並計算表示式的值。其中的toPolishNotation()方法將中綴表示式轉換為字首表示式(波蘭式)、toReversePolishNotation()方法則用於將中綴表示式轉換為字尾表示式(逆波蘭式):

注:
(1) 程式很長且註釋比較少,但如果將上面的理論內容弄懂之後再將程式編譯並執行起來,還是比較容易理解的。有耐心的話可以研究一下。(2) 此程式是筆者為了說明上述概念而編寫,僅做了簡單的測試,不保證其中沒有Bug,因此不要將其用於除研究之外的其他場合。

  1. package qmk.simple_test;  
  2. import java.util.Scanner;  
  3. import java.util.Stack;  
  4. /** 
  5.  * Example of converting an infix-expression to 
  6.  * Polish Notation (PN) or Reverse Polish Notation (RPN). 
  7.  * Written in 2011-8-25 
  8.  * @author QiaoMingkui 
  9.  */
  10. publicclass Calculator {  
  11.       publicstaticfinal String USAGE = "== usage ==\n"
  12.             + "input the expressions, and then the program "
  13.             + "will calculate them and show the result.\n"
  14.             + "input 'bye' to exit.\n";  
  15.       /** 
  16.        * @param args 
  17.        */
  18.       publicstaticvoid main(String[] args) {  
  19.             System.out.println(USAGE);  
  20.             Scanner scanner = new Scanner(System.in);  
  21.             String input = "";  
  22.             final String CLOSE_MARK = "bye";  
  23.             System.out.println("input an expression:");  
  24.             input = scanner.nextLine();  
  25.             while (input.length() != 0
  26.                   && !CLOSE_MARK.equals((input))) {  
  27.                   System.out.print("Polish Notation (PN):");  
  28.                   try {  
  29.                         toPolishNotation(input);  
  30.                   } catch (NumberFormatException e) {  
  31.                         System.out.println("\ninput error, not a number.");  
  32.                   } catch (IllegalArgumentException e) {  
  33.                         System.out.println("\ninput error:" + e.getMessage());  
  34.                   } catch (Exception e) {  
  35.                         System.out.println("\ninput error, invalid expression.");  
  36.                   }  
  37.                   System.out.print("Reverse Polish Notation (RPN):");  
  38.                   try {  
  39.                         toReversePolishNotation(input);  
  40.                   } catch (NumberFormatException e) {  
  41.                         System.out.println("\ninput error, not a number.");  
  42.                   } catch (IllegalArgumentException e) {  
  43.                         System.out.println("\ninput error:" + e.getMessage());  
  44.                   } catch (Exception e) {  
  45.                         System.out.println("\ninput error, invalid expression.");  
  46.                   }  
  47.                   System.out.println("input a new expression:");  
  48.                   input = scanner.nextLine();  
  49.             }  
  50.             System.out.println("program exits");  
  51.       }  
  52.       /** 
  53.        * parse the expression , and calculate it. 
  54.        * @param input 
  55.        * @throws IllegalArgumentException 
  56.        * @throws NumberFormatException 
  57.        */
  58.       privatestaticvoid toPolishNotation(String input)  
  59.                   throws IllegalArgumentException, NumberFormatException {  
  60.             int len = input.length();  
  61.             char c, tempChar;  
  62.             Stack<Character> s1 = new Stack<Character>();  
  63.             Stack<Double> s2 = new Stack<Double>();  
  64.             Stack<Object> expression = new Stack<Object>();  
  65.             double number;  
  66.             int lastIndex = -1;  
  67.             for (int i=len-1; i>=0; --i) {  
  68.                   c = input.charAt(i);  
  69.                   if (Character.isDigit(c)) {  
  70.                         lastIndex = readDoubleReverse(input, i);  
  71.                         number = Double.parseDouble(input.substring(lastIndex, i+1));  
  72.                         s2.push(number);  
  73.                         i = lastIndex;  
  74.                         if

    相關推薦

    字首中綴字尾表示式

    關鍵字:概念, 字首表示式, 字首記法, 中綴表示式, 中綴記法, 波蘭式, 字尾表示式, 字尾記法, 逆波蘭式 它們都是對錶達式的記法,因此也被稱為字首記法、中綴記法和字尾記法。它們之間的區別在於運算子相對與運算元的位置不同:字首表示式的運算子位於

    ——計算機系統知識(計算機體系結構指令系統資料存放方式)

    計算機體系結構 巨集觀上按處理機數量???——》單處理系統、並行處理與多處理系統、分散式處理系統; 微觀上按並行處理程度???——》Flynn分類法、馮澤雲分類法、Handler分類法、Kuck分

    ——網路與資訊保安基礎知識(IP地址WWW服務網路安全)

    Internet???——》 在邏輯上是統一的、獨立的,在物理上則由不同的網路互連而成;???——》通過路由器 (IP閘道器) 並藉助各種通訊線路或公共通訊網路把它們連線起來; 互相傳遞資訊的眾多

    ——軟體工程基礎知識(資料流程圖資料字典)

    資料流程圖(DFD)???——》一種便於使用者理解、分析系統資料流程的圖形工具;???——》擺脫了系統的物理內容,精確地在邏輯上描述系統的功能、 輸入、輸出和資料儲存等,是系統邏輯模型的重要組成部分 ; 資料流圖的基本圖形元屬???——》資料流(data flow)、加

    ——面向物件技術(互動圖構件圖組合結構圖協作圖部署圖包圖)

    互動圖???——》對系統的動態方面進行建模; 互動圖組成???——》物件、訊息、生命線等; 互動圖表現???——》序列圖、通訊圖、互動概覽圖、計時圖、狀態圖; 順序圖主要元素

    ——網路與資訊保安基礎知識(區域網廣域網/協議)

    計算機網路的硬體裝置是承載計算機通訊的實體,但它們是怎樣有序地完成計算機之間通訊任務的呢???——》協議; 協議???——》規定通訊時的資料格式、資料傳送時序以及相應的控制資訊和應答訊號等內容;

    ——網路與資訊保安基礎知識(計算機網路發展歷程計算機網路的分類)

    計算機網路???——》計算機技術與通訊技術相結合的產物; 計算機網路發展歷程???——》“終端一計算機網”、“計算機一計算機網” 、現代具有統一網路體系結構的計算機網路; 具有通訊功能的單機

    考前 設計模式總結

    總:      設計模式分為 建立型,結構型和行為型 建立型:抽象了例項化的過程,系統關於這些物件知道的是由物件類所定義的介面。              一個類建立模式使用繼承改變被

    下午題 解題思路總結

    總:      下午題就是閱讀理解題,考察的是對題幹資訊的理解總結能力。 分: 試題一 考察資料流圖 1-3題    (寫實體名,資料儲存,補充缺失的資料流及其起點和終點。)可以一起做。 方法: 在加工的描述文字

    TCP & UDP

    TCP  狀態機 TCP 穩定連線 三次握手,四次揮手。用於流量控制,擁塞控制。 左側為A,右側為B。   UDP UDP 傳送資料包之後就沒事了 基於 UDP 的“城會玩”的五個例子 我列舉幾種“城會玩”的例子

    ——面向物件技術(1)

    面向物件???——》一種具有構造繼承性、 封裝性和多型的程式設計語言族的命名;               ???——》一種程式設計風格; 面向物件???——》物件 + 分類 + 繼承 + 

    ——面向物件技術(3)

    物件圖???——》展現了某一時刻一組物件以及它們之間的關係;描述了在類圖中所建立的事物的例項的靜態快照; 建立系統的靜態設計檢視或靜態程序檢視???——》使用物件圖對物件結構進行建模;???——》從

    ——防火牆系統簡要知識

    防火牆(也稱防護牆)???——》一種位於內部網路與外部網路之間的網路安全系統; 背景???——》由Check Point創立者Gil Shwed於1993年發明國際網際網路並引入(US5606668

    作業系統

    前言 根據作業系統的功能複習相關知識點。 程序管理 基本概念 程序是作業系統中資源分配的最小單位。 三態圖 等待也稱阻塞(等待除CPU以外的資源),就緒(等待CPU資源),執行 五

    ——網路與資訊保安基礎知識(2)

    20世紀70年代末,國際化標準組織ISO提出了開放系統互連參考模型OSI/RM;???——》為了實現不同廠家生產的計算機系統之間以及不同網路之間的資料通訊; 開放系統互連參考模型???——》定義異種

    ——網路與資訊保安基礎知識(3)

    那麼這篇就是有關與組建網路的基礎知識???——》 雖然是教材中的例子,但是我會整理的更有利於各位讀者們閱讀; 區域網的基本組成部件???——》伺服器(核心)、客戶端、網路裝置、通訊介質、

    ——面向物件(4)

    Diagram  VS  Diagram Sequence Diagram  VS  Collaboration diagram???——》 同點:在語義上等價,可以相互轉化;???——》都是互動

    ——機器數及其運算

    機器數和真值的概念:           機器數:一個數在計算機中的二進位制表示形式;           真值:帶符號位的機器數對應的真正數值(十進位制的數)稱為真值;           原碼:符號位+真值的絕對值(二進位制);

    ——軟體工程基礎知識(Web應用系統分析與設計)

    WebApp的特性 WebApp屬性???——》網路密集性、併發性、無法預知的負載量、效能、可用性、資料驅動; web應用系統分析的模型型別???——》 內容模型???——》給出由Web應

    ——網路與資訊保安基礎知識(媒體)

    媒體???——》 資訊的物理載體; 承載資訊的載體; 媒體分類???——》 感覺媒體???——》直接作用於人的感覺器官,使人產生直接感覺的;