中綴轉字尾 逆波蘭表示

2021-08-04 15:09:47 字數 3520 閱讀 5111

計算機無法識別數學表示式中的括號以及四則運算的先後順序,因此需要把數學表達示轉換成一種計算機能識別的,逆波蘭表示就能很好的解決這個問題。逆波蘭表示是數學表示式中的一種不需要括號的字尾表達法。即把乙個中綴數學表示式改變成乙個字尾表示。中綴表示的意思就是運算子在要計算的數字中間,而字尾表示就是運算子在要計算的數字之後。

例如:9+(3-1)*3+6/2   這就是乙個中綴表示,和正常的數學表示式一樣

931-3*+62/+     這就是乙個字尾表示

轉換規則:

1.從左到右遍歷中綴表示式的每乙個數字和符號,若是數字就輸出,即成為字尾表示式的一部分;

2.若是符號,則判斷其與棧頂符號的優先順序,是右括號或優先順序不高於棧頂符號(乘除優先加減)則棧頂元素依次出棧並輸出,並將當前符號進棧,一直到最終輸出字尾表示式為止;若是左括號或者優先順序高於棧頂符號則入棧。

以上面的例子為例說明規則:  (假定同一優先順序在棧內的優先順序高於棧外優先順序)

1.從左到右依次遍歷的第乙個字數是9,因為是數字,不入棧,照常輸出;

2.第二個字元是+,因為是符號,同時棧內為空,則入棧;

3.第三個字元是(,因為是左括號,入棧;

4.第四個字元是3,因為是數字,不入棧,照常輸出;

5.第五個字元是-,因為其優先順序比(低,入棧;

6.第六個字元是1,因為是數字,不入棧,照常輸出;

7.第七個字元是),因為是右括號,棧中靠近棧頂的第乙個左括號之後的所有元素輸出,該例中則把棧頂元素-輸出,同時棧中的左括號(出棧,但是並不輸出,右括號)也不輸出;        //此時棧中就剩下字元+

8.第八個字元是*,因為其優先順序高於棧頂元素+,入棧;

9.第九個字元是3,因為是數字,不入棧,照常輸出;  

10.第十個字元是+,因為其優先順序低於棧頂元素*,因此,棧頂元素*輸出,此時棧中的棧頂元素變為字元+,因為先進棧的優先順序高於後進棧(可理解為同一優先順序中棧內的優先順序高於棧外的優先順序),因此棧頂元素+輸出,此時,棧為空,字元+入棧;(當然,假如棧中還存在元素,但是其棧頂元素優先順序高於當前遍歷字元的優先順序,同樣把當前遍歷的字元入棧,如第5步;反之,繼續把棧中元素輸出,直到棧頂元素優先基高於當前遍歷的字元或者棧為空為止)

11.12.13各位看官根據我說的自己試著寫一下吧。最後結果就在上面哦。

上面所述是中綴轉字尾的具體實施步驟,根據這寫出**還是有一定難度的,當然大神除外,大神的話就不需要看下面了。

**的實現的難度在於怎麼去很好的區分四則運算符的優先順序,以及括號的優先順序,還有棧內棧外的優先順序。為解決這個麻煩事,作了以下假定:

棧內      數值                    棧外        數值

-             4                         -             3

+            4                        +             3

*             6                        *              5

/             6                        /              5

(             2                       (               10

)              2

解釋下:加減的優先順序低於乘除的優先順序,且棧外的加減的優先順序低於棧內的優先順序,因此可以假設用數值3代表棧外的加減,棧內的加減的優先順序要比棧外高,因此只需要把數值加1即可,即4,同理可得乘除的,括號這比較特殊,左邊的括號在棧外時其優先順序要最大才行,因為遇到左括號就需要入棧,但是在棧中時為了能讓其他的再進來,就必須又要保證它的優先順序最小才行,右括號一遍歷到就需要把離棧頂最近的左括號上的所有元素都輸出,而且括號不要輸出,所以可以假定右括號在棧外的數值和棧中左括號值相等,當出現相等的情況時就能明白有一對括號出現。

說了一堆是不是沒看懂啊,沒關係,我現在就附上我寫的**,不過我這**有很大的侷限性,不過解決這個中綴轉字尾是沒什麼問題的。(侷限性就讓各位看官自己猜吧)

這是main.cpp檔案

#include"stack.h"

int main()

這是stack.h檔案
#pragma once

#include#include#include#include#define maxsize 30

#define elemtype char

typedef struct

sqstack;

void init_stack(sqstack *s); //初始化棧

bool my_push(sqstack *s, elemtype value); //入棧

bool my_pop(sqstack *s,elemtype *p); //出棧

bool mid_lat(sqstack *s, char *p); //中綴轉字尾

int sign_fig(char *p); //符號轉換成數值

這是stack.cpp檔案
#include"stack.h"

void init_stack(sqstack *s) //初始化棧

bool my_push(sqstack *s, elemtype value) //入棧

s->top++;

s->data[s->top] = value;

return true;

}bool my_pop(sqstack *s,elemtype *p) //出棧

*p = s->data[s->top];

s->top--;

return true;

}int sign_fig(char *p) //符號轉換成數值 }

bool mid_lat(sqstack *s, char *p)

else

else

else

//比較數值,確定優先順序
//棧內數值小於棧外數值時,即棧內棧頂元素的優先順序低於棧外優先順序
//則棧外元素進棧
if (num_in < num_out)  

//棧內數值大於棧外數值時,則出棧,輸出
else if (num_in > num_out)

//相等時,代表出現了一對括號,棧中左括號出棧,但是不輸出

else

}} }

while (s->top != -1) //遍歷完後,清空棧內元素,把還存在棧中的符號輸出

*q = '\0'; //因為是用字串來表示表示式,最後需要新增『\0』

return true;

}

中綴轉字尾 逆波蘭

具體步驟如下 遇到括號時 重複步驟2至5,直到表示式的最右邊 將s1中剩餘的運算子依次彈出並壓入s2 依次彈出s2中的元素並輸出,結果的逆序即為中綴表示式對應的字尾表示式 例如 中綴表示式 1 2 3 4 5 轉成字尾表示式 123 4x 5 實現 只考慮正整數 public class polan...

逆波蘭計算 中綴轉字尾 字尾表示式計算

我們利用棧將中綴表示式轉換為字尾表示式 逆波蘭表示式 來計算表示式 此程式支援整數運算 遍歷中綴表示式,遇到運算元就輸出,遇到符號就壓入棧中 棧中的運算子為掛起狀態 但是操作符的壓棧出棧有如下規則 碰到運算元壓入棧中,碰到運算子提取棧頂兩個元素進行相應的操作,將運算元壓入棧中,直到整個表示式遍歷完成...

逆波蘭中綴轉字尾表示式並求值

建立鏈棧 linkstack.h pragma once typedef int elemtype typedef struct node node typedef struct linkstack linkstack,ptrstack 初始化 void init ptrstack stack 入棧...