逆波兰(加、减、乘、除、括号)表达式原理及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 阅读(2467) 评论(0) 编辑 收藏 举报