中缀转后缀
前提:這里假設每個英語字母都表示一個數,或者每一個數都是只有一個數字的。(要是可以自己再調整一下,就很容易改好了)
方法:
1. 如果是英語字母,或者是數字,就直接放到返回串里面
2. 如果是空格就直接跳過
3. 如果是右括號),就把棧中的字符都清出來,一直遇到一個左括號
4. 如果是左括號,那就直接放到棧中(沒有人的優先級比這個小了)
5. 剩下的就是運算符。就一直清棧,一直到棧頂的優先級比當前字符要小
6. 最后的把棧中的字符全都清出來
簡單證明:
第二條,有空格,直接跳過,沒有問題(為了提高容錯性的)。
第一條,遇到了數字,或者是英語字母,就直接放到返回串中,這個也沒有問題,總要放數字嘛。
第三條,遇到了一右括號,那么,很顯然,這一堆的運算符,都是會被一個左括號和右括號給囊括的,所以,需要把還沒有被清走的表達式給清走
第四條,在描述的時候,已經說了,左括號優先級最小,自己先放就好了
第五條,關鍵的一條,如果前面的運算級大于或者等于當前運算符的集合,那么說明前面的那些需要先算(唯一可能懷疑的就是那個相等的時候,這個其實是一個定義問題,也可以用不等于的,但是為了節省空間,就先把等于的情況給拿出來)
第六條,最后,如果前面的都沒有把操作符輸出的話,就清棧。這是顯然的,因為你只是轉換,并不會減少運算符(把括號不算運算符)。我們只需要證明,如果有棧到這個時候是非空的,就可以了。
a+b
上述例子就完成了說明。
代碼如下:歡迎批評指正,共同學習
#include<iostream> using namespace std; #include<stack> stack<string> oper; string mid2Post(string s){string ans;for (int i = 0; i < s.size(); ++i){if (s[i] >= '0' && s[i] <= '9' || s[i] >= 'a' && s[i] <= 'z' ||s[i] >= 'A' && s[i] <= 'Z'){ans += s.substr(i,1);ans += string(" ");} else if (s[i] == ' '){continue;} else if (s[i] == ')'){// this is a opernent ')'while (!oper.empty() && oper.top() != "(") {ans += oper.top();ans += string(" ");oper.pop();}if (!oper.empty())oper.pop();} else if (s[i] == '(') {oper.push(s.substr(i,1));} else { // 一直出棧,直到有比當前要小的字符出現 while (!oper.empty() &&( ( (oper.top() == "+" || oper.top() == "-" || oper.top() == "*" || oper.top() == "/")&& (s[i] == '+' || s[i] == '-') ) || ((s[i] == '*' || s[i] == '/') && (oper.top() == "*" ||oper.top() =="/"))) ) {ans += oper.top();ans += string(" ");oper.pop();} oper.push(s.substr(i,1));}}while (!oper.empty()){ans += oper.top();ans += string(" ");oper.pop();}return ans; }int main(){string s;cin >> s;cout << mid2Post(s)<< endl; }歡迎關注我用于做筆記的公眾號:肥宅Sean筆記
總結
- 上一篇: 堆排序(C\C++)
- 下一篇: gcc: error: CreatePr