一个c++做的计算器
2008-11-27 17:17 Iron 阅读(1008) 评论(0) 编辑 收藏 举报今天看了一本书,有个用c++写的计算器,简洁明了,共享出来
1 #include <iostream> 2 #include <stack> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 double read_and_evaluate(istream & ins); 7 void evaluate_stack_tops(stack <double> &numbers, stack<char> &operations); 8 int main() 9 { 10 double answer; 11 cout << "input a expression:" << endl; 12 answer = read_and_evaluate(cin); 13 cout << "The result of your expression is :" << answer << endl; 14 return 1; 15 } 16 double read_and_evaluate(istream & ins) 17 { 18 const char DECIMAL = '.'; 19 const char RIGHT_PARENTHESIS = ')'; 20 stack<double> numbers; 21 stack<char> operations; 22 double number; 23 char symbol; 24 while(ins && ins.peek() != '\n') 25 { 26 if( isdigit(ins.peek()) || (ins.peek() == DECIMAL) ) 27 { 28 ins >> number; 29 //测试 30 cout << number <<endl; 31 numbers.push(number); 32 } 33 else if(strchr( "+-*/", ins.peek() ) != NULL) 34 { 35 ins >> symbol; 36 operations.push(symbol); 37 } 38 else if( ins.peek() == RIGHT_PARENTHESIS ) 39 { 40 ins.ignore(); 41 evaluate_stack_tops( numbers, operations ); 42 } 43 else 44 { 45 ins.ignore(); 46 } 47 } 48 return numbers.top(); 49 } 50 void evaluate_stack_tops(stack <double> &numbers, stack<char> &operations) 51 { 52 double operand1, operand2; 53 54 operand2 = numbers.top(); 55 numbers.pop(); 56 operand1 = numbers.top(); 57 numbers.pop(); 58 switch(operations.top()) 59 { 60 case '+': 61 numbers.push(operand1 + operand2); 62 break; 63 case '-': 64 numbers.push(operand1 - operand2); 65 break; 66 case '*': 67 numbers.push(operand1 * operand2); 68 break; 69 case '/': 70 numbers.push(operand1 / operand2); 71 break; 72 } 73 operations.pop(); 74 } 75 //以下是自己写的,算是做个笔记 76 #include <iostream> 77 #include <stack> 78 using namespace std; 79 const int EXIT_SUCESS = 1; 80 //判断是否为数字 81 bool isNumber(char single_char) 82 { 83 if(single_char >= '0' && single_char <= '9') 84 return true; 85 else 86 return false; 87 } 88 //计算器类 89 class Calculator 90 { 91 public: 92 char decimalPoint; 93 char rightBracket; 94 string operationString; 95 double result; 96 stack<double> numbers; 97 stack<char> operations; 98 Calculator(); 99 void getAndtranslateexpression(istream & ins); 100 double calculate(); 101 void clear();//清空堆栈 102 }; 103 //计算类构造函数 104 Calculator::Calculator() 105 { 106 decimalPoint = '.'; 107 rightBracket = ')'; 108 operationString = "+-*/"; 109 } 110 void Calculator::getAndtranslateexpression( istream & ins ) 111 { 112 double number; 113 char operation; 114 //清理堆栈 115 this->clear(); 116 //进行计算 117 while( ins && ins.peek() != '\n') 118 { 119 if( isNumber(ins.peek()) || ins.peek() == decimalPoint ) 120 { 121 ins >> number; 122 numbers.push(number); 123 } 124 else if( operationString.find( ins.peek() ) != string::npos ) 125 { 126 ins >> operation; 127 operations.push( operation ); 128 } 129 else if( ins.peek() == ')' ) 130 { 131 ins.ignore(); 132 calculate(); 133 } 134 else 135 { 136 ins.ignore(); 137 } 138 } 139 ins.ignore(); 140 //末尾没加括号处理 141 while( numbers.size() != 1 ) 142 { 143 calculate(); 144 } 145 //赋结果给result 146 result = numbers.top(); 147 } 148 //计算处理函数 149 double Calculator::calculate() 150 { 151 double number1 , number2; 152 char operation; 153 number2 = numbers.top(); 154 numbers.pop(); 155 number1 = numbers.top(); 156 numbers.pop(); 157 operation = operations.top(); 158 operations.pop(); 159 switch(operation) 160 { 161 case '+': 162 numbers.push(number1 + number2); 163 break; 164 case '-': 165 numbers.push(number1 - number2); 166 break; 167 case '*': 168 numbers.push(number1 * number2); 169 break; 170 case '/': 171 numbers.push(number1 / number2); 172 break; 173 } 174 } 175 void Calculator::clear() 176 { 177 //清理堆栈 178 while( !numbers.empty() ) 179 { 180 numbers.pop(); 181 } 182 while( !operations.empty() ) 183 { 184 operations.pop(); 185 } 186 } 187 int main() 188 { 189 double expressionAnswer; 190 cout << "Input a expression:" <<endl; 191 Calculator* myCalculator = new Calculator(); 192 while(1) 193 { 194 myCalculator->getAndtranslateexpression(cin); 195 cout << "The expression's result is " << myCalculator->result <<endl; 196 } 197 delete myCalculator; 198 return EXIT_SUCESS; 199 } 200 以上两个都是直接接收控制台输入而进行计算的,而且必须输入全括号的,这样的话C++就比java或其他语言有了优势,因为c++的cin很强大,但是全括号不符合人们的习惯,cin高级使用也使程序移植产生很大困难,于是我写了一个基于处理字符串表达式的计算器,参考了上面提到的那本书和严蔚敏的《数据结构》,现把c++源码贴出来,希望大家批评指正: 201 //============================================================================ 202 // Name : myCalculator.cpp 203 // Author : 204 // Version : 205 // Copyright : Your copyright notice 206 // Description : Hello World in C++, Ansi-style 207 //============================================================================ 208 209 #include <iostream> 210 #include <stack> 211 #include <vector> 212 #include <cstdlib> 213 using namespace std; 214 //主函数执行完毕返回EXIT_SUCESS 215 const int EXIT_SUCESS = 1; 216 217 //判断是否为数字 218 bool isNumberorpoint(char single_char) 219 { 220 if((single_char >= '0' && single_char <= '9') || (single_char == '.')) 221 return true; 222 else 223 return false; 224 } 225 //过滤字符串,将空格过滤掉 226 void trimString(string& myString) 227 { 228 //建立新字符串,接收过滤后的字符,然后将字串值返回给原来字串 229 string tempString; 230 for( unsigned i = 0; i < myString.length(); ++i ) 231 { 232 if(myString.at(i) != ' ') 233 { 234 tempString += myString.at(i); 235 } 236 } 237 myString = tempString; 238 } 239 //判断运算符优先级 240 char compare(char topChar , char newTopChar) 241 { 242 char operationAera[7][7] = { 243 {'>' , '>' , '<' , '<' , '<' , '>' , '>'}, 244 {'>' , '>' , '<' , '<' , '<' , '>' , '>'}, 245 {'>' , '>' , '>' , '>' , '<' , '>' , '>'}, 246 {'>' , '>' , '>' , '>' , '<' , '>' , '>'}, 247 {'<' , '<' , '<' , '<' , '<' , '=' , ' '}, 248 {'>' , '>' , '>' , '>' , ' ' , '>' , '>'}, 249 {'<' , '<' , '<' , '<' , '<' , ' ' , '='} 250 }; 251 int topCharindex,newTopCharindex; 252 switch(topChar) 253 { 254 case '+': 255 topCharindex = 0; 256 break; 257 case '-': 258 topCharindex = 1; 259 break; 260 case '*': 261 topCharindex = 2; 262 break; 263 case '/': 264 topCharindex = 3; 265 break; 266 case '(': 267 topCharindex = 4; 268 break; 269 case ')': 270 topCharindex = 5; 271 break; 272 case '#': 273 topCharindex = 6; 274 break; 275 } 276 switch(newTopChar) 277 { 278 case '+': 279 newTopCharindex = 0; 280 break; 281 case '-': 282 newTopCharindex = 1; 283 break; 284 case '*': 285 newTopCharindex = 2; 286 break; 287 case '/': 288 newTopCharindex = 3; 289 break; 290 case '(': 291 newTopCharindex = 4; 292 break; 293 case ')': 294 newTopCharindex = 5; 295 break; 296 case '#': 297 newTopCharindex = 6; 298 break; 299 } 300 //cout << operationAera[topCharindex][newTopCharindex]<<endl; 301 return operationAera[topCharindex][newTopCharindex]; 302 } 303 //计算器类 304 class Calculator 305 { 306 public: 307 char decimalPoint; 308 char rightBracket; 309 string operationString; 310 double result; 311 stack<double> numbers; 312 stack<char> operations; 313 Calculator(); 314 //void getAndtranslateexpression(istream & ins); 315 void getAndtranslateexpression( string & insString ); 316 void calculate(); 317 void clear();//清空堆栈 318 }; 319 //计算类构造函数 320 Calculator::Calculator() 321 { 322 //以下三句都是为cin版的getAndtranslateexpression服务的 323 decimalPoint = '.'; 324 rightBracket = ')'; 325 operationString = "+-*/"; 326 } 327 //直接接收cin而进行计算,但这样就只能是全括号的表达式才能正确求值 328 /*void Calculator::getAndtranslateexpression( istream & ins ) 329 { 330 double number; 331 char operation; 332 //清理堆栈 333 this->clear(); 334 //进行计算 335 while( ins && ins.peek() != '\n') 336 { 337 if( isNumberorpoint(ins.peek()) || ins.peek() == decimalPoint ) 338 { 339 ins >> number; 340 numbers.push(number); 341 } 342 else if( operationString.find( ins.peek() ) != string::npos ) 343 { 344 ins >> operation; 345 operations.push( operation ); 346 } 347 else if( ins.peek() == ')' ) 348 { 349 ins.ignore(); 350 calculate(); 351 } 352 else 353 { 354 ins.ignore(); 355 } 356 } 357 ins.ignore(); 358 //末尾没加括号处理 359 while( numbers.size() != 1 ) 360 { 361 calculate(); 362 } 363 //赋结果给result 364 result = numbers.top(); 365 }*/ 366 //getAndtranslateexpression函数string版 367 void Calculator::getAndtranslateexpression( string & insString ) 368 { 369 unsigned currentPosOfinsString = 0; 370 unsigned numberEndpos = 0; 371 trimString(insString); 372 insString += '#'; 373 double number; 374 char operation , lastOperation; 375 operations.push('#'); 376 for( currentPosOfinsString = 0; currentPosOfinsString < insString.length(); ++currentPosOfinsString ) 377 { 378 numberEndpos = currentPosOfinsString; 379 loop: 380 currentPosOfinsString = numberEndpos; 381 operation = insString.at(currentPosOfinsString); 382 if( currentPosOfinsString == 0 ) 383 { 384 lastOperation = '1';//这里是数字说小数点字符就行 385 } 386 else 387 { 388 lastOperation = insString.at(currentPosOfinsString - 1); 389 } 390 //cout <<operation<<endl; 391 if( operation == '-' && !isNumberorpoint( lastOperation ) ) 392 { 393 //如果为负数,则特别处理 394 ++numberEndpos; 395 for( int j = currentPosOfinsString + 1; currentPosOfinsString < insString.length(); j++ ) 396 { 397 if( isNumberorpoint( insString.at( j ) ) ) 398 { 399 ++numberEndpos;//标记向后移 400 } 401 else 402 { 403 break; 404 } 405 } 406 //cout << currentPosOfinsString <<endl; 407 //cout<< insString.substr(currentPosOfinsString , numberEndpos - currentPosOfinsString) <<endl; 408 number = atof(insString.substr(currentPosOfinsString , numberEndpos - currentPosOfinsString).c_str()); 409 numbers.push(number); 410 cout <<number<<endl; 411 currentPosOfinsString = numberEndpos; 412 goto loop;//用当前非数字字符继续进行判断,这里如果用continue,那当前的非数字字符,将不被下一次读取,也就是,处理过程将它漏掉了,这是程序所不允许的 413 } 414 else if( isNumberorpoint( operation ) ) 415 { 416 for( int j = currentPosOfinsString; currentPosOfinsString < insString.length(); j++ ) 417 { 418 if( isNumberorpoint( insString.at( j ) ) ) 419 { 420 ++numberEndpos;//标记向后移 421 } 422 else 423 { 424 break; 425 } 426 } 427 //cout << currentPosOfinsString <<endl; 428 //cout<< insString.substr(currentPosOfinsString , numberEndpos - currentPosOfinsString) <<endl; 429 number = atof(insString.substr(currentPosOfinsString , numberEndpos - currentPosOfinsString).c_str()); 430 numbers.push(number); 431 cout <<number<<endl; 432 currentPosOfinsString = numberEndpos; 433 goto loop;//用当前非数字字符继续进行判断,这里如果用continue,那当前的非数字字符,将不被下一次读取,也就是,处理过程将它漏掉了,这是程序所不允许的 434 } 435 else 436 { 437 //++numberEndpos; 438 //currentPosOfinsString = numberEndpos; 439 //cout<< operation <<endl; 440 switch(compare( operations.top() , operation )) 441 { 442 //算术过程 443 case '<': 444 operations.push( operation ); 445 break; 446 case '=': 447 operations.pop(); 448 break; 449 case '>': 450 calculate(); 451 goto loop;//用当前非数字字符继续进行判断,例如如果当前是')',那么括号内算完后还得执行一次此过程,使得左括号从栈中消去 452 break; 453 } 454 } 455 } 456 result = numbers.top(); 457 } 458 //计算处理函数 459 void Calculator::calculate() 460 { 461 double number1 , number2; 462 char operation; 463 number2 = numbers.top(); 464 numbers.pop(); 465 number1 = numbers.top(); 466 numbers.pop(); 467 operation = operations.top(); 468 operations.pop(); 469 switch(operation) 470 { 471 case '+': 472 numbers.push(number1 + number2); 473 break; 474 case '-': 475 numbers.push(number1 - number2); 476 break; 477 case '*': 478 numbers.push(number1 * number2); 479 break; 480 case '/': 481 numbers.push(number1 / number2); 482 break; 483 } 484 } 485 void Calculator::clear() 486 { 487 //清理堆栈 488 while( !numbers.empty() ) 489 { 490 numbers.pop(); 491 } 492 while( !operations.empty() ) 493 { 494 operations.pop(); 495 } 496 } 497 int main() 498 { 499 cout << "Input a expression:" <<endl; 500 Calculator* myCalculator = new Calculator(); 501 string expression;// = "3-(7.2*2)"; 502 cin >> expression; 503 myCalculator->getAndtranslateexpression(expression); 504 cout << "The expression's result is " << myCalculator->result <<endl; 505 delete myCalculator; 506 return EXIT_SUCESS; 507 }