看Mark Aliens的Data Structure and Algorithm Analysis时,发现一个不错的四则运算算法,下面做下了下简单的实现。 代码实现如下,欢迎大家拍砖。 /******************************************************************** created: 2009/10/09 created: 9:10:2009 18:43 filename: BaseOperate.cpp file path: c:/Jackafx_App/BaseOperator file base: BaseOperate file ext: cpp author: jackafx purpose: arithmetic algorithm *********************************************************************/ #include <iostream> #include <string> #include <stack> #include <queue> #include <math.h> #include <stdlib.h> using namespace std; #ifndef UINT typedef unsigned int UINT; #endif stack<string> Stack; stack<double> Output; queue<string> Queue; char OpList[] = { '+', '-', '*', '/', '(', ')' }; double Calculate( const char op, bool& bSuccess ) { double a, b; double fResult = 0; bSuccess = false; b = Output.top(); Output.pop(); a = Output.top(); Output.pop(); switch ( op ) { case '+': fResult = a + b; bSuccess = true; break; case '-': fResult = a - b; bSuccess = true; break; case '*': fResult = a * b; bSuccess = true; break; case '/': fResult = a / b; bSuccess = true; break; default: break; } return fResult; } double Calculate( string op, bool& bSuccess ) { char chop = op[0]; return Calculate( chop, bSuccess ); } UINT GetPriority( string op ) { string str_op = op; UINT uiPriority = 0; if ( str_op == "+" || str_op == "-" ) { uiPriority = 1; } else if ( str_op == "*" || str_op == "/") { uiPriority = 2; } else ; // do nothing return uiPriority; } bool Operate( string op ) { string str_in = op; double dReuslt = 0; bool bsuccess = false; UINT uiPriority = GetPriority( str_in ); if ( uiPriority == 0 ) { if ( str_in == "(" ) { Stack.push( str_in ); } else if ( str_in == ")" ) { while ( Stack.top() != "(" ) { dReuslt = Calculate( Stack.top(), bsuccess ); if ( bsuccess ) { Output.push( dReuslt ); Stack.pop(); } else return false; } Stack.pop(); // pop the "(" } else { dReuslt = atof( str_in.c_str() ); Output.push( dReuslt ); // it's a number, just do it. } return true; } // normal operator // and we need do something here while ( !Stack.empty() && GetPriority( Stack.top() ) >= uiPriority ) { dReuslt = Calculate( Stack.top(), bsuccess ); if ( bsuccess ) { Output.push( dReuslt ); Stack.pop(); } else return false; } Stack.push( str_in ); // finally, push the operator return true; } bool IsOperator( const char op ) { int nIndex = 0; while ( nIndex < 6 ) { if ( OpList[nIndex] == op ) return true; nIndex++; } return false; } bool PutStrToQueue( char* str ) { char* pOp = str; string str_put_in; string tmp; while ( *pOp != '/0' ) { tmp = *pOp; if ( IsOperator( *pOp ) ) { if ( !Queue.empty() && !str_put_in.empty() ) { Queue.push( str_put_in ); // it's ok } // check weather it is empty, if not, clear it. if ( !str_put_in.empty() ) str_put_in.clear(); Queue.push( tmp ); } else { str_put_in.append( tmp ); // put the characters together } pOp++; } pOp--; if ( *pOp != ')') { Queue.push( str_put_in ); } return true; } int main( ) { string test; PutStrToQueue( "((10+5)*(9-6)-13*14)*2" ); while ( !Queue.empty() ) { test = Queue.front(); if ( !Operate( test ) ) return -1; Queue.pop(); } // then, do the rest of work while( !Stack.empty() ) { test = Stack.top(); if ( !Operate( test ) ) return -1; Stack.pop(); } return 0; }