表达式求值(中)

原创 2003年10月28日 23:47:00
 

// Expression.cpp: implementation of the CExpression class.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

//

//////////////////////////////////////////////////////////////////////

 

#include "stdafx.h"

#include "Expression.h"

#include "math.h"

 

const  int funTableLen = 17;  //函数表长度

double sign(double x);

static  double ( * funTable[ ] )( double ) = {

    acos, asin, atan,

              ceil, cos,  cosh,  exp,

              fabs, floor, log,  log10,

              sin,  sinh,  sqrt,

              tan,  tanh, sign

}; //单参数函数入口地址表

 

static char funNameTable[ ][6] = {

    "acos", "asin", "atan", "ceil", "cos", "cosh", "exp", "fabs",

              "floor",  "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh", "sign"

};    //函数名表

 

//////////////////////////////////////////////////////////////////////

// CVar Class

//////////////////////////////////////////////////////////////////////

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CVar::CVar()

{

       InitVar();

}

 

CVar::~CVar()

{

      

}

void CVar::InitVar()

{

     m_cFlag=1;   

        m_strName="";

     m_strSlave="";      

     m_dValue=0;  

}

//////////////////////////////////////////////////////////////////////

// CVarList Class

//////////////////////////////////////////////////////////////////////

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CVarList::CVarList()

{

      

}

 

CVarList::~CVarList()

{

       list<CVar*>::iterator iter;

       for(iter=m_VarList.begin();iter!=m_VarList.end();iter++)

       {

              delete (*iter);

       }

       m_VarList.clear();

}

bool CVarList::AddVar(CVar *pVar)

{

       m_VarList.insert(m_VarList.end(),pVar);

       return true;

}

 

 

 

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

 

CExpression::CExpression()

{

       m_iErrFlag=0;

       m_iFunFlag=0;

       m_iMatchFlag=0;

    m_dResult = 0;

       m_bDegUnit=true;

       m_strExp=NULL;

       strcpy(m_strToken,"");

}

 

CExpression::~CExpression()

{

      

}

 

bool CExpression::CalExp()

{

    bool ret;

      

       m_iErrFlag=0;

       m_iFunFlag=0;

       m_iMatchFlag=0;

    m_dResult = 0;

      

    if( strlen(m_strExp)==0)

       {

              m_iErrFlag = 1;

              Error();

              return false;

       }

       UpdateSlaveVar();

      

    //取表达式第一单元(利用m_strExp)

    if(GetToken() == true)

    {

              //进入高优先级运算

              ret = Level1(&m_dResult);

             

              //若高级运算出现错误(m_iErrFlag被设置)

              if(ret == false)

              {

                     //打印错误信息

                     Error();

                     return false;

              }

              else

                     return true;

    }

      

    //从表达式中取符号错误

    m_iErrFlag = 2;

    Error();

    return false;

}

void CExpression::Error()

{

    switch(m_iErrFlag)

    {

       case 1:

              Message( "表达式为空!" );

              break;

       case 2:

              Message( "变量或函数非法或语法错误!/n表达式无法计算!" );

              break;

       case 3:

              Message("括号不匹配!");       //"括号不匹配!"

              break;

    }

      

}

 

void CExpression::Message(const char *strMsg)

{

//       printf("/n%s/n",strMsg);

}

 

 

bool CExpression::GetToken()

{

    register char *temp;

      

    m_cTokenType = 0;

      

    //指针指向token的首地址

    temp = m_strToken;

      

    //跳过空格及TAB

    while(IsWhite(*m_strExp) == true)

              m_strExp++;

      

    //首字符是为运算符

    if(IsInStr(*m_strExp,"+-*/%^=(),") == true)

    {

              m_cTokenType = DELIMITER;

              *temp++ = *m_strExp++;

              *temp = 0;

              return true;

    }

      

    //首字符为ASSCI字符或汉字

    else if( isalpha(*m_strExp) || (*m_strExp > 127) || (*m_strExp < 0) )

    {

              //找到字符串结尾

              while(IsDelim(*m_strExp) != true)

                     *temp ++ = *m_strExp++;

             

              *temp = 0;

             

              if(IsFunc( m_strToken ) )

              {

                     m_cTokenType = FUNCTION;

                     return true;

              }

             

              //搜索变量表,判断取得的符号是否为变量

              string  sToken = m_strToken;

              list<CVar*>::iterator iter;

             

              for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)

              {

                     if((*iter)->m_strName == sToken )

                     {

                            m_cTokenType = VARIABLE;

                            return true;

                     }

              }

              return false;

    }

      

    //首字符为数字

    else if(isdigit(*m_strExp) || *m_strExp == '.')

    {

              //.50.5处理

              if(*m_strExp == '.')

            *temp++ = '0';

             

              while(IsDelim(*m_strExp) != true)

                     *temp ++ = *m_strExp++;

             

              *temp = 0;

              m_cTokenType = NUMBER;

              return true;

    }

      

    //首字符为NULL

    if(*m_strExp == 0)

    {

              strcpy(m_strToken,"");

             

              //到达结尾

        return true;

       }

    return false;

      

}

 

 

//判断是否为空格或TAB

bool CExpression::IsWhite(char c)

{

    if(c == ' ' || c == 9)

              return true;

    return false;

}

 

//判断是否为分隔符

bool CExpression::IsDelim(char c)

{

    if(IsInStr(c,"+-*/%^=() ,") == true || c == 9 || c == '/r' || c == 0)

              return true;

    return  false;

}

 

//判断是否为函数

bool CExpression::IsFunc(const char *fname)

{

    int i;

    for(i=0;i<funTableLen;i++)

    {

              if(strcmp(fname,funNameTable[i]) == 0)

                     return true;

    }

    return false;

}

 

//判断C是否在串S

bool CExpression::IsInStr(char ch,char *s)

{

    while(*s)

    {

              if(*s++ == ch)

                     return true;

    }

    return false;

}

 

 

double sign(double x)

{

    if(x > 0)

        return x;

    else

        return 0;

}

//赋值运算

bool CExpression::Level1(double *result)

{

    int index,ttok_type;

    char temp_token[80];

      

    //变量单元,有可能是赋值的表达式运算

    if(m_cTokenType == VARIABLE)

    {

              //保留该单元及单元类型

              strcpy(temp_token,m_strToken);

              ttok_type = m_cTokenType;

             

              //若取不到变量在变量表中的索引值

              if(GetVarIndex(m_strToken,&index) != true)

              {

                     m_iErrFlag = 2;

                     return false;

              }

             

              if(GetToken() != true)

              {

                     m_iErrFlag = 2;        //m_iErrFlag = 1;

                     return false;

              }

             

              //若变量后紧跟'=',则为赋值运算,否则为一般运算

              if(*m_strToken != '=')

              {

                     //将刚取得的单元回送到表达式中

                     PutBack();

                    

                     //恢复当前单元变量及变量类型

                     strcpy(m_strToken,temp_token);

                     m_cTokenType = ttok_type;

              }

             

              //若为赋值运算进入下面运算

              else

              {

                     //'='号后面的单元

                     if(GetToken() != true)

                     {

                            m_iErrFlag = 2;        //m_iErrFlag = 1;

                            return false;

                     }

                    

                     //进入高级的+-运算

                     if(Level2(result) == true)

                     {

                            list<CVar*>::iterator iter;

                            int i=0;

                            for(iter=m_VarList.m_VarList.begin();iter!=m_VarList.m_VarList.end();iter++)

                            {

                                   if(i==index)

                                   {

                                          (*iter)->m_dValue=*result;

                                          return true;

                                   }

                                   i++;

                            }

                     }

                     else

                            return false;

              }

    }

      

    //第一单元不是变量,直接进入高优先级+-运算

    if(Level2(result) == true)

              return true;

    else

              return false;

}

 

//加减运算

bool CExpression::Level2(double *result)

{

    register char op;  //运算符

    double     hold=0;      //保留运算中间结果

      

    //直接进入高优先级的*/%运算,没有高级运算才进入下面运算

    if(Level3(result) != true)

              return false;

      

    //若下一单元为+-

    while((op = *m_strToken) == '+' || op == '-')

    {

              //取得+-号后的单元

              if(GetToken() == true)

              {

                     //运算+-号后面的表达式值,有可能又取得+-

                     if(Level3(&hold) == true)

                     {

                            //数学运算,结果直接放在*result

                            bool  bRet = Arith(op,result,&hold);

                            if( bRet == false )

                                   return  false;

                     }

                     else

                            return false;

              }

              else

              {

                     m_iErrFlag = 2;        //m_iErrFlag = 1;

                     return false;

              }

    }

    return true;

}

 

//乘除及求余数运算

bool CExpression::Level3(double *result)

{

    register char op;  //运算符

    double     hold=0;      //保留中间运算结果

      

    //直接进入高优先级运算,没有高级运算才进入下面运算

    if(Level4(result) != true)

              return false;

      

    //若下一单元为*/%

    while((op=*m_strToken) == '*' || op == '/' || op == '%')

    {

              //取得运算符后的单元

              if(GetToken() == true)

              {

                     //运算*/%后的表达式值,有可能又获得*/%

                     if(Level4(&hold) == true)

                     {

                            //数学运算,结果放在*result

                            bool  nRet = Arith(op,result,&hold);

                            if( nRet == false )

                                   return  false;

                     }

                     else

                            return false;

              }

              else

              {

                     m_iErrFlag = 2;        //m_iErrFlag = 1;

                     return false;

              }

    }

    return true;

}

 

//乘方运算

bool CExpression::Level4(double *result)

{

    register char op;  //运算符

    double     hold=0;      //保留中间运算结果

      

    //直接进入高优先级运算,没有高级运算才进入下面运算

    if(Level5(result) != true)

              return false;

      

    //若下一单元为^(乘方)

    while((op=*m_strToken) == '^')

    {

              if(GetToken() == true)

              {

                     //取得运算符后的单元

                     if(Level5(&hold) == true)

                     {

                            //运算^后的表达式值,有可能又获得^

                            bool  nRet = Arith(op,result,&hold);

                            if( nRet == false )

                                   return  false;

                     }

                     else

                            return false;

              }

              else

              {

                     m_iErrFlag = 2;        //m_iErrFlag = 1;

                     return false;

              }

    }

    return true;

}

 

 

 

//单目求反运算

bool CExpression::Level5(double *result)

{

    register char op = 0;

      

    if((m_cTokenType == DELIMITER) && *m_strToken == '+' || *m_strToken == '-' )

    {

              //若表达式第一单元为+号或-,记录该运算符

              op = *m_strToken;

             

              //取得下一单元

              if(GetToken() != true)

              {

                     m_iErrFlag = 2;        //m_iErrFlag = 1;

                     return false;

              }

    }

      

    //进入高优先级运算

    if(Level6(result) != true)

              return false;

      

    //进入高优先级运算

    if(op)

              Unary(op,result);

      

    return true;

}

Java字符串算数表达式求值

原文地址:http://blog.csdn.net/yhhazr/article/details/7947962 [java] view plain copy ...
  • tanga842428
  • tanga842428
  • 2016年10月13日 21:52
  • 707

C++ - 表达式求值顺序

在C++里,表达式求值顺序一直是一个大坑,这是由于为了给编译器更大的优化空间,C++对表达式的求值做了许多非常灵活的规定(其实就是不规定,编译器愿意怎么实现都可以)。这些灵活的规定也给C++带来了许多...
  • fefe82
  • fefe82
  • 2014年07月15日 22:35
  • 2947

表达式求值(栈)

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达...
  • lp15203883326
  • lp15203883326
  • 2016年07月20日 16:50
  • 538

使用栈解决表达式求值(C语言)及问题总结

一、理论知识 表达式=(操作数)+(运算符)+(操作数)设 Exp = S1+OP+S2则称OP+S1+S2为前缀表示法 S1+OP+S2为中缀表示法         S1+S2+OP为后缀表示法 例...
  • F__shigang
  • F__shigang
  • 2017年03月15日 13:14
  • 1252

数据结构课程设计---------用栈来实现表达式求值

1、需求分析 设计一个程序,演示用算符优先法对算术表达式求值的过程。利用算符优先关系,实现对算术四则混合运算表达式的求值。 (1)输入的形式:表达式,例如2*(3+4)      包含的运算符只...
  • Hackbuteer1
  • Hackbuteer1
  • 2011年08月12日 21:40
  • 47305

Java-Stack实现中序表达式求值

中序表达式:对人而言是很直观的(我们平时计算时接触最多的表达式),但计算机处理起来比较麻烦(括号、优先级之类的),前序和后序表达式中没有括号,而且在计算中只需单向扫描,不需要考虑运算符的优先级。如2+...
  • Chen__Haowei
  • Chen__Haowei
  • 2017年04月22日 13:29
  • 889

表达式求值算法总结

表达式求值算法表达式求值,一般采用栈和队列的方式来求值,下面介绍表达式求值的两种算法。方法一、使用两个栈,一个为操作符栈OPTR(operator),一个是操作数栈OPND(operand) 算法过...
  • honglicu123
  • honglicu123
  • 2016年09月18日 16:00
  • 803

MATLAB符号表达式->函数->求值

有时候需要解符号表达式得到某个量关于其他量的显式表达式,MATLAB解出的结果任然是符号表达式,我们希望可以用这个表达式构造函数,进一步求值。...
  • u010909667
  • u010909667
  • 2016年10月08日 21:19
  • 1428

栈的应用之算术表达式求值

栈是一种后进先出的数据结构。表达式求值是对栈的一个典型的应用。 对于如下一个表达式: 1 + 2 * (3 + 4) 此算术表达式由一些操作符和操作数组成。其中,操作符有‘+’、‘*’、‘(...
  • zjdnwpu
  • zjdnwpu
  • 2016年04月28日 22:12
  • 3905

表达式求值源代码

/*小弟刚学c数据结构 这是清华大学严蔚敏数据结构那本书上的用堆栈实现的 自己写的不好的地方 各位大哥恳请指教用#做为表达式结束符*/ #include #define STACK_SIZE 100 ...
  • zvoll
  • zvoll
  • 2007年03月20日 21:52
  • 822
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:表达式求值(中)
举报原因:
原因补充:

(最多只允许输入30个字)