堆疊經典應用 表示式求值 字尾表示式

2021-07-05 06:14:09 字數 2161 閱讀 4761

引言

表示式求值的思路可以是直接處理中綴表示式,也可以採用字尾表示式進行轉換求值,這篇文章將按照以下思路:

優先順序的概念

->什麼是中綴字尾表示式

->字尾表示式的優點

->中綴表示式如何轉換為字尾表示式

->字尾表示式的運算

->具體**實現

優先順序

表示式求值是乙個資料結構中的經典問題,要求對表示式中的運算優先順序不能忽略,在此現規定運算子的優先順序如下:

*』 『/』 > 『+』 『-』 > 『(』 『)

即乘除大於加減,加減大於左右括號

什麼是字尾表示式?

例如:1+2*3,是我們常見的表示式,稱為中綴表示式,而與之對應的字尾表示式是123*+。 這種將運算子置於運算元其後的表示式稱作字尾表示式,具體運算為:每當遇到乙個運算子就取運算子前兩個數進行運算。

字尾表示式的好處

例如常見的乙個中綴表示式:

(a+b)*c+d/(e+c)

其對應的字尾表示式為

ab+c*dec+/+

可以發現字尾表示式能夠忽略括號,減少運算的複雜度,且結合運用堆疊能夠很好地計算出結果

中綴表示式如何轉字尾表示式?

按照以下規則從前向後可以得到對應的字尾表示式:

1、遇到數字直接加入字尾表示式。

2、遇到空棧則直接入棧。

3、遇到運算子』(『,直接入棧。

4、遇到運算子』)』,不斷彈棧直到遇到』(『,但』(『和』)』都不能加入表示式。

5、其它運算子的優先順序若比棧頂運算小,則彈出棧頂符號加入到字尾表示式中,並再次比較棧頂元素。

字尾表示式的運算

其實運算規則在前文已經提到了:每遇到乙個操作符就取其前的兩個運算元進行運算,例如在字尾表示式31+2*2/中:

第一步遇到+ 計算結果 42*2/

第一步遇到* 計算結果 82/

第一步遇到/ 計算結果 4

具體**實現

#include

#include

#include

using

namespace

std;

string infix; //原本的表示式

string postfix; //逆波蘭式,即字尾表示式

stack

stc; //用於存放運算子的堆疊

int charcompare(char c); //字元比較

void infixtopostfix(); //表示式轉換

void calculate(); //計算結果

int oper(int num1,char op,int num2);//計算乙個子表示式

int main()

int charcompare(char c)

return ci;

}void infixtopostfix()

else

//如果處理的是操作符

stc.pop();//彈出'(',不留在堆疊中

}else

//遇到其它操作符先進行比較,再彈棧

stc.push(c);//完成彈棧後插入}}

}while (!stc.empty())

}int oper(int num1, char op, int num2)

return res;

}void calculate()

else

//當遇到操作符時,取棧頂兩個數進行運算

}while (itstr!=postfix.end());

cout

<< inst.top();

}

字尾表示式求值

字尾表示式求值過程中不需要考慮運算子的優先順序,只需要對該表示式中的每乙個元素進行判斷,若為運算元則將其儲存在乙個陣列裡 入棧 若為運算子則取出前面的兩個運算元 彈棧 並運算,並將運算結果放回該陣列 入棧 最終陣列的最後乙個元素 棧頂元素 即為該表示式的運算結果.如 字尾表示式 23 等價於中綴表示...

字尾表示式求值

題目描述 為了便於處理表示式,常常將普通表示式 稱為中綴表示 轉換為字尾sqstack 順序棧的初始化 status initstack sqstack s 順序棧的入棧 status push sqstack s,selemtype e 演算法3.3 順序棧的出棧 status pop sqsta...

字尾表示式求值

根據 逆波蘭表示法,求表示式的值。有效的算符包括 每個運算物件可以是整數,也可以是另乙個逆波蘭表示式。說明 整數除法只保留整數部分。給定逆波蘭表示式總是有效的。換句話說,表示式總會得出有效數值且不存在除數為 0 的情況。示例 1 輸入 tokens 2 1 3 輸出 9 解釋 該算式轉化為常見的中綴...