中缀表达式转化为后缀表达式
一、從應對考試角度來(在最快的時間內得出最準確的答案)
首先我們應該知道,要想將中綴轉化為后綴,需要借助堆棧實現。(不準備畫圖了,畫圖有點浪費時間)我會用最簡單明了的語言使讀者弄懂。[舉個例子吧:比如將:2*(9+6/3-5)+4轉化為后綴表達式2 9 6 3 / +5 -? * 4 +? ? ]
1、任何中綴表達式都由運算數,運算符,括號(大,中,小),這三部分組成。
2、從中綴表達式的左邊開始掃描(腦中自己想像的),若遇到運算數時,則直接將其輸出(不壓入堆棧)。
3、若遇到左括號,則將其壓棧。
4、若遇到右括號,表達括號內的中綴表達式已經掃描完畢。這時需將棧頂的運算符依次彈出并輸出,直至遇到左括號[左括號彈出但不輸出]。
5、若遇到的是運算符:a、如果該運算符的優先級大于棧頂運算符的優先級時,將其壓棧
????????????????????????????????? ? b、如果該運算符的優先級小于棧頂運算符的優先級時,將棧頂運算符彈出并輸出,接著和新的棧頂運算 符比較,若大于,則將其壓棧,若小于,繼續將棧頂運算符彈出并輸出......(一直遞歸下去,直至運算符大于棧頂云算符為止)。
6、最后一步,若掃描到中綴表達式的末尾[即掃描結束],若堆棧中還有存留的運算符依次彈出并輸出即可。
原文:https://blog.csdn.net/coder_dacyuan/article/details/79941743
?
CODE:
/* 中綴轉后綴C++代碼實現(比較方便) 1.遇到操作數:添加到后綴表達式中或直接輸出 2.棧空時:遇到運算符,直接入棧 3.遇到左括號:將其入棧 4.遇到右括號:執行出棧操作,輸出到后綴表達式,直到彈出的是左括號 注意:左括號不輸出到后綴表達式 5.遇到其他運算符:彈出所有優先級大于或等于該運算符的棧頂元素,然后將該運算符入棧 6.將棧中剩余內容依次彈出后綴表達式 */#include<iostream> #include<stack> #include<queue> #include<map> #include<string> #include<cstdio> #define MAX 100 using namespace std;//設置優先級(注意默認操作數的優先級最高,即其不需要進棧,進棧的都是運算符) map<char, int> p;//一些初始化******************************************** struct Node{double num;//操作數char op;//操作符bool flag;//true表示操作數,false表示操作符 }; typedef struct Node node;stack<node> s;//操作符棧 stack<node> s1;//存放操作數的,為了計算后綴表達式的值 queue<node> q;//后綴表達式隊列//****************************************************** //中綴轉后綴函數 void change(string str){node temp;for (int i = 0; i < str.length();){if (str[i] == '('){//3.遇到左括號:將其入棧temp.flag = false;temp.op = str[i];s.push(temp);i++;}else if (str[i] == ')'){//4.遇到右括號:執行出棧操作,輸出到后綴表達式,直到彈出的是左括號while (!s.empty() && s.top().op != '('){q.push(s.top());s.pop();}s.pop();//彈出左括號i++;}else if (str[i] >= '0'&&str[i] <= '9'){//如果是數字temp.flag = true;temp.num = str[i] - '0';i++;//后移一位,因為數字不一定是個位數while (i < str.length() && str[i] >= '0'&&str[i] <= '9'){temp.num = temp.num * 10 + (str[i] - '0');i++;}q.push(temp);//操作數進入后綴表達式}else{//如果是操作符//5.遇到其他運算符:彈出所有優先加大于或等于該運算符的棧頂元素,然后將該運算符入棧temp.flag = false;while (!s.empty() && p[s.top().op] >= p[str[i]]){q.push(s.top());s.pop();}temp.op = str[i];s.push(temp);i++;}}//6.將棧中剩余內容依次彈出后綴表達式while (!s.empty()){q.push(s.top());s.pop();} }//************************************************************* //后綴表達式的計算 /* 從左到右掃描后綴表達式 1)若是操作數,就壓棧, 2)若是操作符,就連續彈出兩個操組數 3)棧頂的值即為所需結果 注:先彈出的是第一操作數,后彈出的是第二操作數 */ double calculate(){double num_a, num_b;//操作數a,bnode cur, temp;while (!q.empty()){//后綴隊列非空cur = q.front();//記錄隊首元素q.pop();if (cur.flag == true){//是操作數進入棧s1.push(cur);}else{//是操作符就運算num_b = s1.top().num;s1.pop();//彈出第二操作數num_a = s1.top().num;s1.pop();//彈出第一操作數temp.flag = true;if (cur.op == '+'){temp.num = num_a + num_b;}else if (cur.op == '-'){temp.num = num_a - num_b;}else if (cur.op == '*'){temp.num = num_a * num_b;}else{temp.num = num_a / num_b;}s1.push(temp);//把計算后的結果再次壓棧}}return s1.top().num;} //*************************************************************int main() {string str;p['+'] = p['-'] = 1;//通過hashmap賦值p['*'] = p['/'] = 2;cin >> str;change(str);//*****************************************************//中綴轉后綴/*while (!q.empty()){cur = q.front();if (cur.flag == true) cout << cur.num << " ";else cout << cur.op << " ";q.pop();}*/while (!s1.empty()){//初始化棧s1s1.pop();}double answer=calculate();cout << answer<<endl;return 0; }
?
轉載于:https://www.cnblogs.com/zhangbuang/p/11177898.html
總結
以上是生活随笔為你收集整理的中缀表达式转化为后缀表达式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows自带反编译chm文件
- 下一篇: docker (centOS 7) 使用