引言
表示式求值的思路可以是直接處理中綴表示式,也可以採用字尾表示式進行轉換求值,這篇文章將按照以下思路:
優先順序的概念
->什麼是中綴字尾表示式
->字尾表示式的優點
->中綴表示式如何轉換為字尾表示式
->字尾表示式的運算
->具體**實現
優先順序
表示式求值是乙個資料結構中的經典問題,要求對表示式中的運算優先順序不能忽略,在此現規定運算子的優先順序如下:
『*』 『/』 > 『+』 『-』 > 『(』 『)』
即乘除大於加減,加減大於左右括號
什麼是字尾表示式?
例如: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 解釋 該算式轉化為常見的中綴...