逆波兰(加、减、乘、除、括号)表达式原理及C++代码实现

当我们输入一个数学表达式,是中缀表达式,我们首先转换为后缀表达式(逆波兰表达式),然后再进行求值。

 

代码思路:

(1)首先对输入的中缀表达式合法性进行判断,bool isStringLegal(const char* str); 函数实现。

(2)然后把中缀表达式转换为后缀表达式。

(3)根据后缀表达式求出结果,double getTheResult(vector<string> &vec);函数实现。

注意:表达式的运算符可以输入 加、减、乘、除、括号,输入的数据为整形数据,计算结果为double型数据。

  1 #include <iostream>
  2 #include <math.h>
  3 #include <map>
  4 #include <vector>
  5 #include <string.h>
  6 #include <memory>
  7 #include <string>
  8 #include <stdio.h>
  9 #include <stack>
 10 #include <stdlib.h>
 11 
 12 using namespace std;
 13 
 14 #define MAX_STRING_LENGTH 100
 15 
 16 /* 解析当前的整形数据,并把整形数据转换为string型 */
 17 string analyData(const char* str, int &i);
 18 
 19 /* 根据逆波兰表达式求表达式的值 */
 20 double getTheResult(vector<string> &vec);
 21 
 22 /* 判断该字符是否是 + - * / ( ) */
 23 bool isCalChar(const char ch);
 24 
 25 /* 判断输入的中缀表达式是否合法 */
 26 bool isStringLegal(const char* str);
 27 
 28 
 29 
 30 /* 解析当前的整形数据,并把整形数据转换为string型 */
 31 string analyData(const char* str, int &i)
 32 {
 33     int temp = i++;
 34     while(str[i] >= '0' && str[i] <= '9' && str[i] != '\0')
 35     {
 36         i++;
 37     }
 38 
 39     string s(str+temp,str+i);
 40 
 41     return s;
 42 }
 43 
 44 /* 根据逆波兰表达式求表达式的值 */
 45 double getTheResult(vector<string> &vec)
 46 {
 47     vector<string>::iterator it;
 48     stack<double> sta;
 49 
 50     string strTemp;
 51     double d = 0, d1 = 0, d2 = 0;
 52 
 53     for(it = vec.begin(); it != vec.end(); it++)
 54     {
 55         strTemp = (*it);
 56 
 57         if(strTemp == "+")
 58         {
 59             d1 = sta.top();
 60             sta.pop();
 61 
 62             d2 = sta.top();
 63             sta.pop();
 64 
 65             d = d1 + d2;
 66             sta.push(d);
 67         }
 68         else if(strTemp == "-")
 69         {
 70             d1 = sta.top();
 71             sta.pop();
 72 
 73             d2 = sta.top();
 74             sta.pop();
 75 
 76             d = d2 - d1;
 77             sta.push(d);
 78         }
 79         else if(strTemp == "*")
 80         {
 81             d1 = sta.top();
 82             sta.pop();
 83 
 84             d2 = sta.top();
 85             sta.pop();
 86 
 87             d = d2 * d1;
 88             sta.push(d);
 89         }
 90         else if(strTemp == "/")
 91         {
 92             d1 = sta.top();
 93             sta.pop();
 94 
 95             d2 = sta.top();
 96             sta.pop();
 97 
 98             d = d2 / d1;
 99             sta.push(d);
100         }
101         else
102         {
103             const char *p = strTemp.c_str();
104             d = atoi(p);
105             sta.push(d);
106         }
107     }
108     return sta.top();
109 }
110 
111 /* 判断该字符是否是 + - * / ( ) */
112 bool isCalChar(const char ch)
113 {
114     if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '('  || ch == ')')
115     {
116         return true;
117     }
118 
119     return false;
120 }
121 /* 判断输入的中缀表达式是否合法 */
122 bool isStringLegal(const char* str)
123 {
124     /* 判断是否是空串 */
125     if(NULL == str)
126     {
127         return false;
128     }
129 
130     int len = strlen(str);
131     int i = 0;
132     int flag = 0;
133 
134     /* 字符串的开头和末尾是否是数字 */
135     if(str[0] > '9' || str[0] < '0' || str[len-1] > '9' || str[len-1] < '0')
136     {
137         return false;
138     }
139 
140 
141     for(i = 0; str[i] != '\0'; i++)
142     {
143         /* 是否有除了加减乘除括号之外的字符 */
144         if(isCalChar(str[i]) == false)
145         {
146             return false;
147         }
148 
149         /* 判断是否有两个连续的符号 */
150         if(i < len-1 && isCalChar(str[i]) == true)
151         {
152             if(isCalChar(str[i+1]) == true)
153             {
154                 return false;
155             }
156 
157         }
158 
159         /* 判断括号是否成对 */
160         if(str[i] == '(')
161         {
162             flag++;
163         }
164         else if(str[i] == ')')
165         {
166             flag--;
167         }
168 
169         /* 判断是否出现 )( 这样的情况 */
170         if(flag < 0)
171         {
172             return false;
173         }
174     }
175 
176     /* 判断括号是否匹配 */
177     if(flag != 0)
178     {
179         return false;
180     }
181 
182     return true;
183 }
184 
185 int main(void)
186 {
187     char str[MAX_STRING_LENGTH] = {0};
188     int i = 0;
189     string data;
190 
191     /* 存放运算符表达式的栈 */
192     stack<char> oper_char;
193 
194     /* 存放后缀表达式 */
195     vector<string> post_str;
196 
197     /* 输入中缀的表达式 */
198     gets(str);
199 
200     /* 判断输入的中缀表达式是否合法 */
201     if(isStringLegal(str) != true)
202     {
203         cout << "This expression is not legal." << endl;
204     }
205     else
206     {
207         /* 将中缀表达式转换为后缀表达式 */
208         for(i = 0; str[i] != '\0'; i++)
209         {
210             /* 如果该字符为数字,解析该数字,并压入栈 */
211             if(str[i] >= '0' && str[i] <= '9')
212             {
213                 data = analyData(str,i);
214                 post_str.push_back(data);
215                 i--;
216             }
217             else if(str[i] == '(')
218             {
219                 oper_char.push(str[i]);
220             }
221             else if(str[i] == ')')
222             {
223                 char chtemp[2] = {0};
224 
225                 chtemp[0] = oper_char.top();
226 
227                 while(chtemp[0] != '(')
228                 {
229                     string strtemp(chtemp);
230                     post_str.push_back(strtemp);
231                     oper_char.pop();
232 
233                     chtemp[0] = oper_char.top();
234                 }
235                 oper_char.pop();
236             }
237             else if(str[i] == '+' || str[i] == '-')
238             {
239                 char chtemp[2] = {0};
240 
241                 /* 全部出栈,但是碰到 '('就要停止出栈 */
242                 while(oper_char.size() != 0)
243                 {
244                     chtemp[0] = oper_char.top();
245                     if(chtemp[0] == '(')
246                     {
247                         break;
248                     }
249 
250                     oper_char.pop();
251 
252                     string strtemp(chtemp);
253                     post_str.push_back(strtemp);
254                 }
255 
256                 /*将当前的表达式符号入栈*/
257                 oper_char.push(str[i]);
258             }
259             else if(str[i] == '*' || str[i] == '/')
260             {
261                 char chtemp[2] = {0};
262                 while(oper_char.size() != 0)
263                 {
264                     chtemp[0] = oper_char.top();
265                     if(chtemp[0] == '(' || chtemp[0] == '+' || chtemp[0] == '-')
266                     {
267                         break;
268                     }
269                     else
270                     {
271                         oper_char.pop();
272 
273                         string strtemp(chtemp);
274                         post_str.push_back(strtemp);
275                     }
276                 }
277 
278                 /*将当前的表达式符号入栈*/
279                 oper_char.push(str[i]);
280             }
281         }
282 
283         /* 存放表达式的栈可能还有数据 */
284         while(!oper_char.empty())
285         {
286             char chtemp[2] = {0};
287             chtemp[0] = oper_char.top();
288             oper_char.pop();
289 
290             string strtemp(chtemp);
291             post_str.push_back(strtemp);
292         }
293 
294         /* 把逆波兰表达式求值 */
295         cout << getTheResult(post_str) << endl;
296     }
297 
298     return 0;
299 }

 

posted on 2017-12-13 10:45  kenny.wmh  阅读(2212)  评论(0编辑  收藏  举报

导航