其他语言

本类阅读TOP10

·基于Solaris 开发环境的整体构思
·使用AutoMake轻松生成Makefile
·BCB数据库图像保存技术
·GNU中的Makefile
·射频芯片nRF401天线设计的分析
·iframe 的自适应高度
·BCB之Socket通信
·软件企业如何实施CMM
·入门系列--OpenGL最简单的入门
·WIN95中日志钩子(JournalRecord Hook)的使用

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
算术表达式解析类

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

提供一个类,字符串表达式解析,不过,表达式容错能力很弱。

源码如下:

class CalcExp
{
public:
 CalcExp();
 ~CalcExp();
 double GetResult(LPSTR);
private:
 double FindNextValue(LPSTR lpExp, LPSTR &lpRet);
 char FindNextOP(LPSTR lpExp, LPSTR &lpRet);
 int  CompareOP(char chOp1, char chOp2);
 int  GetLevel(char chOP);
 double  GetValue(char chOpType, double dLValue, double dRValue);
 double CalcExpr(LPSTR);
private:
 LPSTR m_pszBuff;
 TCHAR m_szBuffForTest[1024];
};

CalcExp::CalcExp()
{
 m_pszBuff = NULL;

 strcpy(m_szBuffForTest, "");
}

CalcExp::~CalcExp()
{
// delete []m_pszBuff;
}

double CalcExp::FindNextValue(LPSTR lpExp, LPSTR &lpRet)
{
 char szTmp[256];
 
 memset(szTmp, 0, 256);

 LPSTR lpTmp = szTmp;

 while (lpExp && *lpExp != '\0' && (!isdigit(*lpExp)) && (*lpExp != '.'))
 {
  lpExp ++;
 }
 
 BOOL bHasDot = FALSE;

 while (lpExp && *lpExp != '\0' && ((isdigit(*lpExp)) || (*lpExp == '.' && !bHasDot)))
 {

  if(*lpExp == '.')
  {
   bHasDot = TRUE;
  }

  *lpTmp = *lpExp;
  lpExp ++;
  lpTmp++;
 }
 
 if(szTmp[0] == 0)
 {
  lpRet = NULL; 
 }
 else
 {
  lpRet = lpExp;
 }

 return atof(szTmp);
}

char CalcExp::FindNextOP(LPSTR lpExp, LPSTR &lpRet)
{
 char szOpers[] = "+-*/()";
 char chRtn = 0;

 while (lpExp && *lpExp != '\0')
 {
  if(strchr(szOpers, *lpExp))
  {
   chRtn = *lpExp;

   break;
  }

  lpExp ++;
 }

 if(lpExp && *lpExp != '\0')
 {
  lpExp++; 
  lpRet = lpExp;
 }
 else
 {
  lpRet = NULL;
 }

 return chRtn;
}

int  CalcExp::CompareOP(char chOp1, char chOp2)
{
 if(chOp2 == ')')
 {
  return 1;
 }
 
 if(chOp1 == '(')
 {
  return -1;
 }

 if(chOp2 == '(')
 {
  return - 1;
 }

 
 int iLevel1, iLevel2;
 
 iLevel1 = GetLevel(chOp1);
 iLevel2 = GetLevel(chOp2);

 if(iLevel1 == iLevel2)
 {
  return 0;
 }

 if(iLevel1 > iLevel2)
 {
  return 1;
 }

 if(iLevel1 < iLevel2)
 {
  return -1;
 }
}

int  CalcExp::GetLevel(char chOP)
{
 char szOpers[4][4] = {")","+-","*/", "("};

 for(int iLevel = 0; iLevel < 4; iLevel++)
 {
  if(strchr(szOpers[iLevel], chOP))
  {
   return iLevel;
  }
 }

 return -1;
}

double CalcExp::CalcExpr(LPSTR lpExp)
{
 double dRtn = 0;

 while(*lpExp == ' ')
 {
  lpExp ++;
 }

 if(*lpExp == '\0')
 {
  return 0;
 }

 double ardValueBuff[1024];
 char   archOPBuff[1024];

 int iValDeep = 0, iOPDeep = 0;
 
 LPSTR lpTmpVal = lpExp, lpTmpOP = lpExp;

 do
 {
  ardValueBuff[iValDeep] = FindNextValue(lpTmpVal, lpTmpVal);
  
  if(lpTmpVal)
  {
   iValDeep++;
  }

  archOPBuff[iOPDeep] = FindNextOP(lpTmpOP, lpTmpOP);

  if(lpTmpOP)
  {
   iOPDeep++;
  }
 } while(lpTmpVal || lpTmpOP);

 for(int iLoop = 0; iLoop < iValDeep / 2; iLoop++)
 {
  double dTmp = ardValueBuff[iLoop];
  ardValueBuff[iLoop] = ardValueBuff[iValDeep - 1 - iLoop];
  ardValueBuff[iValDeep - 1 - iLoop] = dTmp;
 }

 for(iLoop = 0; iLoop < iOPDeep / 2; iLoop++)
 {
  char chTmp = archOPBuff[iLoop];
  archOPBuff[iLoop] = archOPBuff[iOPDeep - 1 - iLoop];
  archOPBuff[iOPDeep - 1 - iLoop] = chTmp;
 }
 
 while(iOPDeep)
 {
  int iValTop = 0, iOPTop = 0;

  if(iOPDeep == 1)
  {
   iOPDeep --;
   iValDeep = 0;
   dRtn = GetValue(archOPBuff[iOPDeep], ardValueBuff[1], ardValueBuff[0]);
   continue;
  }

  while(CompareOP(archOPBuff[iOPDeep - 1], archOPBuff[iOPDeep - 2]) < 0)
  {
   iOPDeep--;
   iOPTop++;
   archOPBuff[1024 - iOPTop]  = archOPBuff[iOPDeep];
   
   if(archOPBuff[iOPDeep] == '(')
   {
    continue;
   }

   iValDeep--;
   iValTop++;
   ardValueBuff[1024 - iValTop]  = ardValueBuff[iValDeep];
  }

  iOPDeep--;
  
  if(archOPBuff[iOPDeep] == '(' && archOPBuff[iOPDeep - 1] == ')')
  {
   iOPDeep--;
  }
  else
  {

   iValDeep--;

   ardValueBuff[iValDeep - 1] = GetValue(archOPBuff[iOPDeep], ardValueBuff[iValDeep], ardValueBuff[iValDeep - 1]);
  }

  while(iOPTop || iValTop)
  {
   if(iOPTop)
   {
    archOPBuff[iOPDeep]  = archOPBuff[1024 -iOPTop];
    iOPTop --;
    iOPDeep++;
   }
   
   if(iValTop)
   {
    ardValueBuff[iValDeep] = ardValueBuff[1024 - iValTop];
    iValTop --;
    iValDeep++;
   }
  }
 }

 if (iValDeep)
 {
  dRtn = ardValueBuff[0];
 }
 
 return dRtn;
}

double  CalcExp::GetValue(char chOpType, double dLValue, double dRValue)
{
 switch(chOpType)
 {
 case '+':
  return dLValue + dRValue;
  break;
 case '-':
  return dLValue - dRValue;
  break;
 case '*':
  return dLValue * dRValue;
  break;
 case '/':
  
  if(dRValue == 0)
  {
   return 0;
  }

  return dLValue / dRValue;
  break;
 }

 return 0;
}

double CalcExp::GetResult(LPSTR lpExp)
{
 strcpy(m_szBuffForTest, lpExp);

 return CalcExpr(lpExp);
}

 




相关文章

相关软件