後綴表達式 詳解

表達式的表示形式有中綴、前綴和後綴3中形式。中綴表達式按操作符的優先級進行計算(後面代碼實現只包括+、-、*、\,小括號),即數學運算。 後綴表達式中只有操作數和操作符。操作符在兩個操作數之後。它的計算規則非常簡單,嚴格按照從左到右的次序依次執行每一個操作。每遇到一個操作符,就將前面的兩個數執行相應的操作。 

由後綴表達式計算中綴表達式原理:計算機處理後綴表達式求值問題是比較方便的,即將遇到的操作數暫存於一個操作數棧中,凡是遇到操作數,便從棧中pop出兩個操作數,並將結果存於操作數棧中,直到對後綴表達式中最後一個操作數處理完,最後壓入棧中的數就是後最表達式的計算結果。 

中綴表達式轉換爲等價的後綴表達式 

中綴表達式不方便與計算機處理,通常要講中綴表達式轉換爲一個與之等價的後綴表達式。等價是指兩個表達式的計算順序和計算結果完全相同。 

中綴表達式:0.3/(5*2+1)# 

的等價後綴表達式是:0.3 5 2 * 1 + /# 

仔細觀察這兩個等價的表達式可知,操作數的出現次序是相同的,但運算符的出現次序是不同的。在後綴表達式中,運算符的出現次序是實際進行操作的次序;在中追表達式中,由於受到操作符的優先級和括號的影響,操作符出現次序與實際進行操作的次序很可能是不一樣的。 

算法描述: 

將中綴表達式轉換爲等價的後綴表達式的過程要使用一個棧放“(”,具體可以按照下面的方式進行。 

(1)從左到右依次掃描中綴表達式的每一個字符,如果是數字字符和圓點“.”則直接將它們寫入後綴表達式中。 

(2)如果遇到的是開括號“(”,則將它們壓入一個操作符棧(不需要與棧頂操作符相比較),它表明一個新的計算層次的開始,在遇到和它匹配的閉括號“)”時,將棧中的元素彈出來並放入後綴表達式中,直到棧頂元素爲“(”時,將棧頂元素“(”彈出(不需要加入後綴表達式),表明這一層括號內的操作處理完畢。 

(3)如果遇到的是操作符,則將該操作符和操作符棧頂元素比較: 

    1、當所遇到的操作符的優先級小於或等於棧頂元素的優先級時,則取 出棧頂元素放入後綴表達式,並彈出該棧頂元素,反覆執行直到當前操作符的優先級大於棧頂元素的優先級小於;

     2、當所遇到的操作符的優先級大於棧頂元素的優先級的時則將它壓入棧中。 


(4)重複上述步驟直到遇到中綴表達式的結束符標記“#”,彈出棧中的所有元素並放入後綴表達式中,轉換結束


代碼如下:

  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<string>  
  5. #include<vector>  
  6. #include<stack>  
  7. #include<algorithm>  
  8. using namespace std;  
  9.   
  10. int pre(char a) //操作符優先級比較  
  11. {  
  12.     if(a == '=' || a == '(')  
  13.         return 0;  
  14.     else if(a == '+' || a == '-')  
  15.         return 1;  
  16.     else if(a == '*' || a == '/')  
  17.         return 2;  
  18. }  
  19.   
  20. int main()  
  21. {  
  22.     int ncase, len;  
  23.     string str;  
  24.     char tmp;  
  25.     stack<char> ope; //操作符  
  26.     vector<char> ans;//後綴表達式  
  27.     vector<char>::iterator start, end;  
  28.     scanf("%d", &ncase);  
  29.     getchar(); //清除輸入垃圾  
  30.     while(ncase--)  
  31.     {  
  32.         while(!ope.empty()) //初始化  
  33.             ope.pop();  
  34.         ans.clear();  
  35.         ope.push('='); //結束標誌  
  36.         cin>>str;  
  37.         len = str.length();  
  38.         for(int i = 0 ; i < len; ++i)  
  39.         {  
  40.             if(str[i] >= '0' && str[i] <= '9'//操作數直接存入ans  
  41.                 ans.push_back(str[i]);  
  42.             else if(str[i] == '('//左括號入棧  
  43.                 ope.push(str[i]);  
  44.             else if(str[i] == ')'//右括號,將匹配的左括號內容存入ans,左括號出棧  
  45.             {  
  46.                 while (ope.top() != '(')  
  47.                 {  
  48.                     ans.push_back(ope.top());  
  49.                     ope.pop();  
  50.                 }  
  51.                 ope.pop(); //左括號出棧  
  52.             }  
  53.             else if(pre(str[i]) > pre(ope.top())) //優先級大於棧頂元素則入棧  
  54.                 ope.push(str[i]);  
  55.             else //小於棧頂元素  
  56.             {  
  57.                 while(pre(str[i]) <= pre(ope.top()))  
  58.                 {  
  59.                     ans.push_back(ope.top());  
  60.                     ope.pop();  
  61.                 }  
  62.                 ope.push(str[i]);  
  63.             }         
  64.         }  
  65.         while(ope.top() != '='//其餘操作符存入後綴表達式中  
  66.         {  
  67.             ans.push_back(ope.top());  
  68.             ope.pop();  
  69.         }  
  70.         for(start = ans.begin(), end = ans.end(); start < end; ++start)  
  71.             printf("%c", *start);  
  72.         printf("\n");  
  73.     }  
  74.     return 0;  
  75. }  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章