1 //表达式求值 数据结构严蔚敏 表达式求值 代码实现 2 #include<iostream> 3 4 using namespace std; 5 6 typedef struct _NODE_ 7 { 8 int a; 9 _NODE_* pNext; 10 }Node,*pNode; 11 12 13 int Precede(int cur,int sta); //优先级判断 函数 14 15 int EvaluateExpression(); //表达式求值 函数 16 17 int Result(int i,int Opr,int j); //结果计算 函数 18 19 bool IsOper(int a); //运算符判读 函数 20 21 22 class CStack //标准链性栈 类 23 { 24 private: 25 pNode m_pHead; 26 int m_iNodeCount; 27 28 29 public: 30 CStack() 31 { 32 m_pHead = NULL; 33 m_iNodeCount = 0; 34 } 35 ~CStack() 36 { 37 38 } 39 40 void InitStack(); 41 42 bool IsEmpty(); 43 44 bool PushStack(int a); 45 46 bool PopStack(int& a); 47 48 int GetTop(); 49 50 int GetLength(); 51 52 void DestroyStack(); 53 }; 54 55 int main() 56 { 57 58 cout<<EvaluateExpression()<<endl; 59 60 61 62 return 0; 63 } 64 65 66 67 void CStack::InitStack() 68 { 69 if(!IsEmpty()) 70 { 71 DestroyStack(); 72 } 73 m_iNodeCount = 0; 74 75 m_pHead = NULL; 76 77 } 78 79 80 81 bool CStack::IsEmpty() 82 { 83 if(m_iNodeCount == 0) 84 { 85 return true; 86 } 87 88 return false; 89 } 90 91 92 93 bool CStack::PushStack(int a) 94 { 95 pNode pNodeTemp = new Node; 96 97 if(pNodeTemp != NULL) 98 { 99 pNodeTemp->a = a; 100 pNodeTemp->pNext = NULL; 101 102 if(m_pHead == NULL) 103 { 104 m_pHead = pNodeTemp; 105 } 106 else 107 { 108 pNodeTemp->pNext = m_pHead; 109 110 m_pHead = pNodeTemp; 111 } 112 113 m_iNodeCount++; 114 115 return true; 116 } 117 118 return false; 119 } 120 121 122 123 bool CStack::PopStack(int& a) 124 { 125 if(IsEmpty()) 126 { 127 return false; 128 } 129 pNode pNodeDel = m_pHead; 130 131 a = m_pHead->a; 132 133 m_pHead = pNodeDel->pNext; 134 135 delete pNodeDel; 136 137 pNodeDel = m_pHead; 138 139 m_iNodeCount--; 140 141 return true; 142 } 143 144 int CStack::GetTop() 145 { 146 return m_pHead->a; 147 } 148 int CStack::GetLength() 149 { 150 return m_iNodeCount; 151 } 152 153 void CStack::DestroyStack() 154 { 155 pNode pNodeDel = m_pHead; 156 157 while(pNodeDel != NULL) 158 { 159 m_pHead = pNodeDel->pNext; 160 161 delete pNodeDel; 162 163 pNodeDel = m_pHead; 164 165 m_iNodeCount--; 166 } 167 } 168 169 /***********************************/ 170 //判断优先级函数 171 //先左后右 172 //先乘除后加减 173 //先括号内,再括号外 174 /***********************************/ 175 176 //括号的优先级应该是最高的 177 //然后是* / > + - 178 //最后是遵循从左往右 179 //+,-,*,/的优先级均 低于 '(' ,但是均高于')'; 180 181 int Precede(int cur,int sta) //cur 当前的运算符 sta 栈顶元素运算符 182 { 183 char f = 0; 184 switch(cur) 185 { 186 case '+': //判断前面的运算符 ( + -优先级一样 ) 187 case '-': 188 { 189 if(sta==' ' || sta=='(') //若为空 或者 ( 就压栈 190 { 191 f = '<'; 192 } 193 else //否则,进行计算 194 { 195 f = '>'; 196 } 197 198 break; 199 } 200 201 case '*': 202 case '/': 203 { 204 if(sta=='*'||sta=='/'||sta==')') //遇到'*' , '/' 或')' 进行计算 205 { 206 f = '>'; 207 } 208 else //其他情况压栈 209 { 210 f = '<'; 211 } 212 213 break; 214 } 215 case '(': 216 { 217 if(sta==')') //不可能会存在 )( 这种情况 218 { 219 cout<<"Error"<<endl; 220 221 exit(0); 222 } 223 else 224 { 225 f = '<'; //遇到其他情况全部压栈 226 } 227 break; 228 } 229 230 case ')': 231 { 232 switch(sta) 233 { 234 case '(': 235 { 236 f = '='; 237 break; 238 } 239 case ' ': 240 { 241 cout<<"Error."<<endl; 242 243 exit(0); 244 break; 245 } 246 default: //遇到此情况,均进行计算 247 { 248 f = '>'; 249 break; 250 } 251 } 252 253 break; 254 } 255 256 case ' ': //' '一般为表达式结尾的标志了。 257 { 258 switch(sta) 259 { 260 case ' ': 261 { 262 f = '='; 263 break; 264 } 265 case '(': 266 { 267 cout<<"Error."<<endl; 268 269 exit(0); 270 } 271 default: 272 { 273 f = '>'; 274 275 break; 276 } 277 } 278 279 break; 280 } 281 } 282 283 return f; 284 } 285 int EvaluateExpression() 286 { 287 288 CStack TableOper; //符号栈 (用来存运算符) 289 CStack TableNum; //数组栈 (用来存数字) 290 291 TableOper.InitStack(); 292 TableNum.InitStack(); 293 294 TableOper.PushStack(' '); 295 296 char a = 0; //存放当前的运算符 297 298 int i = 0; //存放操作数1 299 int j = 0; //存放操作时2 300 int x = 0; //存放TablePer栈中的栈顶元素所代表的运算符 301 302 int PreFlag = TableOper.GetTop(); 303 int NowFlag = TableOper.GetTop(); 304 305 306 a = getchar(); //先接受一个字符 307 308 x = TableOper.GetTop(); 309 310 311 312 while(a!=' ' || x!= ' ') 313 { 314 315 316 317 /**********判断是否是运算符**********/ 318 if(IsOper(a)) 319 { 320 char f = Precede(a,x); //进行优先级判断 321 322 switch(f) 323 { 324 case '<': //如果当前运算符比栈中的运算符优先级低 325 { 326 TableOper.PushStack(a); //那么将当前运算符a 压入栈 327 328 a = getchar(); //接受下一个字符 329 330 NowFlag = TableOper.GetTop(); //NowFlag变为新压入栈的运算符 331 332 break; 333 } 334 case '>': //如果当前运算符比栈中的运算符优先级高 335 { 336 337 TableOper.PopStack(x); //将TableOper(符号栈)栈顶的 运算符 弹出栈,准备作为运算符 338 339 PreFlag = TableOper.GetTop(); //PreFlag为前一个运算符 340 341 TableNum.PopStack(i); //将TableNum(数字栈)的两个待计算的操作数 弹出栈,并分别赋给i,j; 342 343 TableNum.PopStack(j); 344 345 TableNum.PushStack(Result(i,x,j)); // 将计算完毕的结果再压栈压回TableNum中 346 347 break; 348 349 } 350 case '=': //如果优先级相等 351 { 352 353 TableOper.PopStack(x); //TableOper中的栈顶 运算符 弹栈 给 x, 作为 待 操作的运算符 354 355 a = getchar(); //接受新的字符 356 357 break; 358 } 359 } 360 } 361 362 /**********判断是否是数字**********/ 363 else if(a >= '0' && a <= '9') 364 { 365 if(PreFlag == NowFlag) //如果前后的符号标记相等,(即意味着一直在输入数字,如 12 + 34,这里的12 = 1*10 + 2) 366 { 367 if(!TableNum.IsEmpty()) //如果当前的TableNum 数字栈 不为空 368 { 369 int Temp = 0; 370 371 TableNum.PopStack(Temp); //先将前一个被压入TableNum栈的数字弹出给Temp (如弹出1) 372 373 Temp *= 10; //Temp *= 10 (Temp = 10) 374 375 Temp = Temp + a - 48; //Temp 再加上现在的a ,再进去48 (Temp = 10 + 'a' -48 = 10 + 50 - 48 = 12) 376 377 TableNum.PushStack(Temp); //再将Temp 压回到 数字栈 378 379 a = getchar(); //再读入字符 380 } 381 382 383 else //反之,若为空,也就是数字栈中没有数 384 { 385 TableNum.PushStack(a-48); //直接将a-48 压入 数字栈 386 387 a = getchar(); //再读入字符 388 } 389 } 390 391 else //如果前后的符号标记不相等,(即意味着,输入的数字中间有间隔 运算符 如 1 + 2) 392 { 393 PreFlag = NowFlag; //把PreFlag 置为 当前的 运算符 394 395 TableNum.PushStack(a-48); //直接将a-48 压入 数字栈 396 397 a = getchar(); //再读入字符 398 399 } 400 } 401 402 /**********都不是,说明输入的表达式有误**********/ 403 else 404 { 405 cout<<"error"<<endl; 406 407 exit(0); 408 409 } 410 411 x = TableOper.GetTop(); 412 413 } 414 415 416 int ans = 0; //定义一个answer,作为结果返回 417 418 TableNum.PopStack(ans); 419 420 421 return ans; 422 } 423 424 425 426 427 bool IsOper(int a) //判断是否是运算符,这里只是 + - * / ( ) 428 { 429 switch(a) 430 { 431 case '+': 432 case '-': 433 case '*': 434 case '/': 435 case '(': 436 case ')': 437 case ' ': 438 { 439 return true; 440 } 441 442 default: 443 { 444 return false; 445 } 446 } 447 } 448 449 int Result(int i,int Opr,int j) //计算两个数直接的运算结果 450 { 451 switch(Opr) 452 { 453 case '+': 454 return i+j; 455 case '-': 456 return j-i; 457 458 case '*': 459 return j*i; 460 case '/': 461 return j/i; 462 463 default: 464 return-1; 465 } 466 467 }