表达式求值

#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  阅读(357)  评论(0编辑  收藏  举报

导航