表达式求值
#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 阅读(362) 评论(0) 收藏 举报
浙公网安备 33010602011771号