逆波蘭式的轉換與計算(簡單)
阿新 • • 發佈:2019-02-17
我們平常書寫的表示式:--如2+3*4+4 又稱為中綴表示式,我們可以將它轉換為字尾表示式
213*+4+
輸入有兩行,第一行為逆波蘭式的結果,第二行為輸入表示式的正確計算結果。逆波蘭式中相鄰的數字或運算子之間不用輸出空格
保證表示式計算的合理性,不需判斷除零等情況
表示式的計算遵循同級運算從左向右,先乘除後加減
樣例輸入:
2+1*3+4
樣例輸出:
213*+4+
9
解題思路:
首先定義兩個棧,一個臨時儲存運算子S1,另一個作為輸入逆波蘭式S2的存放棧
在S1中先放入一個‘#’運算子調整為最低,方便運算子的比較
然後開始從表示式中取值
(1)若取出的是表示式,直接將其放置到S2存放棧中
(2)若取出的運算子,則將該元素與S1棧頂元素進行比較,如果該運算子優先順序大於(小於或者等於都不行)S1棧頂運算子優先順序,則將該運算子進S1棧,否則,將S1棧棧的棧頂運算子彈出,送入S2棧,之後再和S1現在的棧頂比較,直到運算子優先順序大於棧頂為止後,將該運算子送入S1中
(3)重複上述1-2步,直到所有輸入字元都處理完畢
(4)將S1中的所有符號除‘#’以外都push到S2中
這樣我們就得到了一個逆波蘭序列
計算結果:
將逆波蘭式依次堆入一個棧中,如果堆入的是一個運算子,取出棧裡的頭兩個運算元(必為數字),將其執行運算子所代表的操作後
(一般是 下 運算子 上),將結果放回棧中,最後剩下的棧頂就是結果
程式碼如下:
am> #include <stack> #include <string> #include <vector> #include <algorithm> using namespace std; int precede(char a) { switch (a) { case '+': return 1; case '-': return 1; case '*': return 2; case '/': return 2; case '#': return 0; } } bool comparePrecde(char a,char b) { //前表示式中的元素 後棧中的元素 int pre_a = precede(a); int pre_b = precede(b); if (pre_a > pre_b) { return true; } else { return false; } } int main() { stack<char> numStack; //用來儲存數字 stack<char> exprStack; //用來儲存表示式 stack<char> tempStack; //暫時儲存 stack<float> resStack; //用來儲存計算結果 vector<char> opVec; //正序輸出 exprStack.push('#'); string buffer; //用來讀取中綴表示式 cin >> buffer; for (int i = 0; i < buffer.size(); ++i) { //數字和運算子分離 if (isdigit(buffer[i])) { numStack.push(buffer[i]); } else { while (!comparePrecde(buffer[i], exprStack.top())) { numStack.push(exprStack.top()); exprStack.pop(); } exprStack.push(buffer[i]); } } while (exprStack.top() != '#') { //剩餘的元素壓入棧 numStack.push(exprStack.top()); exprStack.pop(); } while (!numStack.empty()) { opVec.push_back(numStack.top()); tempStack.push(numStack.top()); numStack.pop(); } reverse(opVec.begin(), opVec.end()); //輸出逆波蘭式列 for (auto x : opVec) { cout << x; } cout << endl; //計算結果 while (!tempStack.empty()) { if (isdigit(tempStack.top())) { resStack.push((float)(tempStack.top() - '0')); //char to int tempStack.pop(); } else { char expr = tempStack.top(); tempStack.pop(); float a = resStack.top(); resStack.pop(); float b = resStack.top(); resStack.pop(); switch (expr) { case'+': resStack.push(b + a); break; case'-': resStack.push(b - a); break; case'*': resStack.push(b * a); break; case'/': resStack.push(b / a); break; } } } cout << resStack.top() << endl; //輸出結果 return 0; }