1. 程式人生 > 其它 >C++逆波蘭式轉化成中綴表示式,並輸出最終計算結果

C++逆波蘭式轉化成中綴表示式,並輸出最終計算結果

大學時學資料結構的時候就有練過中綴表示式轉化成逆波蘭式,現在反過來寫個將逆波蘭式轉化成中綴表示式的程式,並輸出最終結果。

1.演算法核心思路:

(1)考慮到需要轉化成中綴表示式,還要計算最終結果,所以設計一個結構體,包含兩個成員變數(運算元、該運算元對應的表示式);

(2)從逆波蘭式第一個字元開始,遇到數字時將該數字字元壓入資料棧(結構體型別),遇到四則運算子壓入運算子棧(字元型),遇到其它字元時丟擲異常;

(3)當運算子棧不為空時,從運算子棧彈出一個運算子,從資料棧中彈出兩個資料,將兩個資料的運算元和運算子進行運算,得到新的資料的運算元,將兩個資料的表示式和運算子組合(運算子為‘*’、‘/’時,需在表示式兩端加上一對小括號),得到新的資料的表示式,將新資料壓入資料棧;

(4)最後只剩下資料棧中只有一個數據,該資料的表示式即最終的中綴表示式,該資料的運算元即最終的計算結果。

2.舉例:

(1)如:逆波蘭式:ab+cd+e*-

   ab+cd+e*- ——> (a+b)cd+e*- ——> (a+b)(c+d)e*- ——> (a+b)(c+d)*e- ——> (a+b)-(c+d)*e

   中綴表示式:(a+b)-(c+d)*e

(2)如:逆波蘭式:12+34+5*-

   12+34+5*- ——> (1+2)34+5*- ——> (1+2)(3+4)5*- ——> (1+2)(3+4)*5- ——> (1+2)-(3+4)*5

   中綴表示式:(1+2)-(3+4)*5

   最終計算結果:-32

   輸出:(1+2)-(3+4)*5=-32

(3)如:逆波蘭式:12+2/34*+

   12+2/34*+ ——> (1+2)2/34*+ ——> (1+2)/234*+ ——> (1+2)/23*4+ ——> (1+2)/2+3*4

   中綴表示式:(1+2)/2+3*4

   最終計算結果:13.5

   輸出:(1+2)/2+3*4=13.5

3.程式碼實現:

  1 #include<iostream>
  2 #include<string>
  3 #include<stack>
  4
using namespace std; 5 6 struct DataNum { 7 float num; //存放運算元 8 string str; //存放運算元對應的式子 9 DataNum(float n, string s) :num(n), str(s) {} 10 }; 11 12 //執行運算,返回運算結果 13 float FuncOperate(float a, float b, char ch) 14 { 15 float result = 0; 16 17 switch (ch) 18 { 19 case '+': result = a + b; break; 20 case '-': result = a - b; break; 21 case '*': result = a * b; break; 22 case '/': result = a / b; break; 23 } 24 25 return result; 26 } 27 28 //逆波蘭式轉換成中綴表示式 29 void FuncRPNtoEquation(string strRPN) 30 { 31 stack<char> stCh; 32 stack<DataNum> stDa; 33 unsigned int i = 0; 34 float num1 = 0, num2 = 0; 35 char ch = ' '; 36 DataNum da(0, ""); 37 38 for (i = 0; i < strRPN.length(); i++) 39 { 40 if ((strRPN[i] >= '0') && (strRPN[i] <= '9')) 41 { 42 da.num = (float)(strRPN[i] - '0'); 43 da.str = "" + to_string((int)da.num); 44 stDa.push(da); 45 } 46 else if ((strRPN[i] == '+') || (strRPN[i] == '-') || (strRPN[i] == '*') || (strRPN[i] == '/')) 47 { 48 stCh.push(strRPN[i]); 49 } 50 else 51 { 52 throw strRPN[i]; 53 } 54 55 //判斷執行算術運算 56 if ((stDa.size() >= 2) && (!stCh.empty())) 57 { 58 ch = stCh.top(); 59 da.str = ch; 60 stCh.pop(); 61 62 num2 = stDa.top().num; 63 da.str = da.str + stDa.top().str; 64 stDa.pop(); 65 66 num1 = stDa.top().num; 67 da.str = stDa.top().str + da.str; 68 stDa.pop(); 69 70 if ((i != strRPN.size() - 1) && (ch != '*') && (ch != '/')) 71 { 72 da.str = "(" + da.str + ")"; 73 } 74 75 da.num = FuncOperate(num1, num2, ch); 76 stDa.push(da); 77 } 78 } 79 80 cout << stDa.top().str << "=" << stDa.top().num << endl; 81 } 82 83 int main() 84 { 85 string str; 86 while (getline(cin, str, '\n')) 87 { 88 if ((str[0] < '0') || (str[0] > '9')) 89 { 90 cout << "Input Error!" << endl; 91 } 92 else 93 { 94 try 95 { 96 FuncRPNtoEquation(str); 97 } 98 catch (char ch) 99 { 100 cout << "'" << ch << "' is illegal!" << endl; 101 } 102 catch (...) 103 { 104 cout << "Error!" << endl; 105 } 106 } 107 } 108 109 return 0; 110 }

4.輸入輸出示範:

(1)示範1:

   輸入:12+34+5*-

   輸出:(1+2)-(3+4)*5=-32

  

(2)示範2:

   輸入:12+2/34*+

   輸出:(1+2)/2+3*4=13.5

  

5.總結:

該程式只能進行個位數的運算,也算是比較基礎的了,不足之處還望各位大佬指正。