表达式求值
#ifndef MAINFUNC_H #define MAINFUNC_H #include <cstring> #include <queue> #include <stack> #include <vector> //1. Get the numbers //2. Modify the expression like (1+1*1)*(1-1); 1 represent one number. //3. the main algorithm using namespace std; class EvaluateExpression { public: explicit EvaluateExpression(); explicit EvaluateExpression(char *p); ~EvaluateExpression(); double getResult(bool &terror); bool judge(); private: void getNumbers();//得到表达式中的值 void modifyExpression(); double getOneNum(vector<char> &tmpNumChars); bool isOperator(char ch); void mainAlg(); int precede(char op1, char op2); double calc(double d1, char oper, double d2); private: char *m_expression; queue<double> m_src_numbers;//numbers in the expression in (10+8) the numbers is 10 and 8 stack<char> m_operation;//save the operators; stack<double> m_oprand; int **m_precede_table; bool m_error; }; #endif // MAINFUNC_H
#include "mainFunc.h" #include <iostream> #include <cstring> #include <stdio.h> #include <ctype.h> EvaluateExpression::EvaluateExpression() { m_error = false; m_expression = NULL; //+ - * / ( ) # //(>==1)(<==-1)(== == 0) (error == -2) int table[7][7]= { { 1, 1,-1,-1,-1, 1, 1 }, { 1, 1,-1,-1,-1, 1, 1 }, { 1, 1, 1, 1,-1, 1, 1 }, { 1, 1, 1, 1,-1, 1, 1 }, { -1,-1,-1,-1,-1, 0,-2 }, { 1, 1, 1, 1,-2, 1, 1 }, { -1,-1,-1,-1,-1,-2, 0 } }; m_precede_table = new int*[7]; for( int i=0;i<7; ++i) { m_precede_table[i] = new int[7]; memcpy(m_precede_table[i],table[i],7*sizeof(int)); } } EvaluateExpression::EvaluateExpression(char *p) { m_error = false; size_t len = strlen(p); // printf("%d\n",len); m_expression = new char[len+1]; strncpy(m_expression,p,len); m_expression[len] = '\0'; // printf("%s\n",m_expression); int table[7][7]= { { 1, 1,-1,-1,-1, 1, 1 }, { 1, 1,-1,-1,-1, 1, 1 }, { 1, 1, 1, 1,-1, 1, 1 }, { 1, 1, 1, 1,-1, 1, 1 }, { -1,-1,-1,-1,-1, 0,-2 }, { 1, 1, 1, 1,-2, 1, 1 }, { -1,-1,-1,-1,-1,-2, 0 } }; m_precede_table = new int*[7]; for( int i=0;i<7; ++i) { m_precede_table[i] = new int[7]; memcpy(m_precede_table[i],table[i],sizeof(table[i])); } cout<<"m_precede_table:"<<m_precede_table[4][5]<<endl; } EvaluateExpression::~EvaluateExpression() { if( NULL!=m_expression ) delete[] m_expression; for( int i=0;i<7;++i) delete[] m_precede_table[i]; delete[] m_precede_table; } double EvaluateExpression::getResult(bool &terror) { this->getNumbers(); this->modifyExpression();//every operand use char '1' to replace; this->mainAlg(); terror = m_error; return m_oprand.top(); } void EvaluateExpression::getNumbers() { if( NULL==m_expression ) return ; while( !m_src_numbers.empty() ) m_src_numbers.pop(); int i=0; vector<char> tmpNums; tmpNums.clear(); while( 0!=m_expression[i] ) { char ch = m_expression[i]; if( !isdigit(ch) && '.'!=ch ) { if( !tmpNums.empty() ) { m_src_numbers.push(this->getOneNum(tmpNums)); tmpNums.clear(); } } if( isdigit(ch) || '.'==ch ) { tmpNums.push_back(ch); } ++i; } if( !tmpNums.empty()) m_src_numbers.push(this->getOneNum(tmpNums)); #if 0 while( !m_src_numbers.empty() ) { cout<<m_src_numbers.front()<<endl; m_src_numbers.pop(); } #endif } double EvaluateExpression::getOneNum(vector<char> &tmpNumChars) { int len = tmpNumChars.size(); double res = 0; double aftDotVal = 0; bool afterDot = false; double pos_ratio=0; for( int i=0; i<len; ++i) { if( isdigit(tmpNumChars[i]) && false==afterDot ) { res = res*10 + (int)(tmpNumChars[i]-'0'); } if( '.'==tmpNumChars[i] ) { afterDot = true; pos_ratio = 1e-1; } if( isdigit(tmpNumChars[i]) && true==afterDot ) { aftDotVal += pos_ratio*(int)(tmpNumChars[i]-'0'); pos_ratio = pos_ratio/10; } } return res + aftDotVal; } void EvaluateExpression::modifyExpression() { size_t pos_before=0; size_t pos_after=0; // printf("%s\n",m_expression); for( pos_before=0; '\0'!=m_expression[pos_before]; ) { if( isdigit(m_expression[pos_before]) || '.'==m_expression[pos_before] ) { m_expression[pos_after++] = 'N'; pos_before++; while( isdigit(m_expression[pos_before]) || '.'==m_expression[pos_before] ) pos_before++; } else m_expression[pos_after++] = m_expression[pos_before++]; // printf("%c\n",m_expression[pos_before]); } // m_expression[pos_after] = '\0'; char *res = new char[pos_after+2];//the '#' and '\0'; strncpy(res,m_expression,pos_after); res[pos_after]='#'; res[pos_after+1]='\0'; delete m_expression; m_expression = res; printf("%s\n",m_expression); } void EvaluateExpression::mainAlg() { while( !m_operation.empty() ) m_operation.pop(); while( !m_oprand.empty() ) m_oprand.pop(); cout<<"size:"<<m_oprand.size()<<endl; m_operation.push('#'); cout<<"numbers"<<m_src_numbers.size()<<endl; size_t i_exp=0; cout<<m_expression<<endl; char ch = m_expression[i_exp]; while( '#'!=ch || '#'!=m_operation.top() ) { if( true==m_error) break; // cout<<"in while"<<endl; if( !isOperator(ch)) { cout<<"size:"<<m_src_numbers.size()<<endl; cout<<m_src_numbers.front()<<endl; m_oprand.push(m_src_numbers.front()); cout<<"size:"<<m_src_numbers.size()<<endl; cout<<"num:"<<m_src_numbers.front()<<endl; m_src_numbers.pop(); ++i_exp; ch = m_expression[i_exp]; cout<<"test"<<endl; // while(1) // ; } else { cout<<"m_operation.top():"<<m_operation.top()<<"ch:"<<ch<<endl; switch ( precede(m_operation.top(),ch)) { case -1://栈顶元素优先权低 m_operation.push(ch); ++i_exp; ch = m_expression[i_exp]; break; case 0: m_operation.pop(); ++i_exp; ch = m_expression[i_exp]; break; case 1: { char choper; choper = m_operation.top(); m_operation.pop(); double num1,num2; num1 = m_oprand.top(); m_oprand.pop(); num2 = m_oprand.top(); m_oprand.pop(); cout<<"num1::"<<num1<<"num2:"<<num2<<endl; cout<<"i_exp"<<i_exp<<endl; cout<<"m_opration:"<<m_operation.top()<<endl; cout<<"ch:"<<ch; double res=0; res = this->calc(num2, choper, num1); cout<<"res:"<<res<<endl; m_oprand.push(res); break; } default: cout<<"erro"<<endl; m_error = true; break; } } } // return m_oprand.top(); } bool EvaluateExpression::isOperator(char ch) { if( '+'==ch || '-'==ch || '*'==ch || '/'==ch || '('==ch || ')'==ch || '#'==ch ) return true; else return false; } int EvaluateExpression::precede(char op1, char op2) { int pos1=0; int pos2=0; if( '+'==op1 ) pos1 = 0; if( '-'==op1 ) pos1 = 1; if( '*'==op1 ) pos1 = 2; if( '/'==op1 ) pos1 = 3; if( '('==op1 ) pos1 = 4; if( ')'==op1 ) pos1 = 5; if( '#'==op1 ) pos1 = 6; if( '+'==op2 ) pos2 = 0; if( '-'==op2 ) pos2 = 1; if( '*'==op2 ) pos2 = 2; if( '/'==op2 ) pos2 = 3; if( '('==op2 ) pos2 = 4; if( ')'==op2 ) pos2 = 5; if( '#'==op2 ) pos2 = 6; return m_precede_table[pos1][pos2]; } double EvaluateExpression::calc(double d1, char oper, double d2) { if( 0==d2 ) { m_error = true; return 0; } if( '+'==oper ) return d1+d2; if( '-'==oper ) return d1-d2; if( '*'==oper ) return d1*d2; if( '/'==oper ) return d1/d2; return -2; } bool EvaluateExpression::judge() { return !m_error; }
#include "mainFunc.h" #include <iostream> using namespace std; int main() { EvaluateExpression ee("(10.01+8)*2"); bool terror=false; double res = ee.getResult(terror); if( terror==true) cout<<"error occurence"<<endl; else cout<<"res:"<<res<<endl; cout << "Hello world!" << endl; return 0; }
posted on 2014-05-16 17:29 jesse_deng 阅读(358) 评论(0) 编辑 收藏 举报