zoukankan      html  css  js  c++  java
  • 表达式求值

    #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
    ",len);
        m_expression = new char[len+1];
        strncpy(m_expression,p,len);
        m_expression[len] = '';
     //   printf("%s
    ",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
    ",m_expression);
        for( pos_before=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
    ",m_expression[pos_before]);
    
        }
     //   m_expression[pos_after] = '';
    
        char *res = new char[pos_after+2];//the '#' and '';
        strncpy(res,m_expression,pos_after);
        res[pos_after]='#';
        res[pos_after+1]='';
        delete m_expression;
        m_expression = res;
        printf("%s
    ",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;
    }
    

      

  • 相关阅读:
    Pentaho BIServer Community Edtion 6.1 使用教程 第三篇 发布和调度Kettle(Data Integration) 脚本 Job & Trans
    Pentaho BIServer Community Edtion 6.1 使用教程 第二篇 迁移元数据 [HSQLDB TO MySQL]
    Pentaho BIServer Community Edtion 6.1 使用教程 第一篇 软件安装
    C调用约定__cdecl、__stdcall、__fastcall、__pascal分析
    django环境搭建和学习
    Nagios学习笔记
    MFC下的DLL编程学习
    从零开始学区块链(4)
    从零开始学区块链(3)
    从零开始学习区块链(2)
  • 原文地址:https://www.cnblogs.com/jesse-deng/p/3732636.html
Copyright © 2011-2022 走看看