📄 expressionbase.cpp
字号:
// Function.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "math.h"
#include "ExpressionBase.h"
#include <ctype.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PI 3.1415926535897932384626433832795
IMPLEMENT_SERIAL(CExpressionBase, CObject, 0)
//////////////////////////////////////////////////////////////////////
// CExpressionBase Class
//////////////////////////////////////////////////////////////////////
CExpressionBase::CExpressionBase()
{
m_Arbore = NULL;
m_definitie = "";
pozitie = 0;
m_pVariabile = NULL;
}
CExpressionBase::CExpressionBase(CMapVariabile * vars)
{
m_Arbore = NULL;
m_definitie = "";
pozitie = 0;
m_pVariabile = vars;
}
CExpressionBase::~CExpressionBase()
{
Elibmem (m_Arbore);
m_pVariabile=NULL;
}
void CExpressionBase::Serialize(CArchive & ar)
{
if (ar.IsStoring())
{
ar << m_definitie;
}
else
{
ar >> m_definitie;
m_Arbore = NULL;
pozitie = 0;
UpdateArbore();
// After loading this object if it contains variables you should atach a variable
// Table to it
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void CExpressionBase::Elibmem(arbore a)
{
if (a==NULL) return;
if (a->left!=NULL) Elibmem(a->left);
if (a->right!=NULL) Elibmem(a->right);
if (a->operatie=='`') delete a->valoarestr;
delete a;
}
int CExpressionBase::UpdateArbore()
{
if (m_definitie.IsEmpty()) return 0;
Elibmem(m_Arbore);
m_Arbore = NULL;
pozitie = 0;
m_Arbore = Expresie();
if (m_definitie[pozitie]!='\0')
{
Elibmem(m_Arbore);
m_Arbore = NULL;
}
if (m_Arbore == NULL) return pozitie;
else return -1;
}
CExpressionBase::arbore CExpressionBase::Expresie()
{
arbore nod;
arbore arb1=Termen();
arbore arb2;
if(arb1 == NULL) return NULL; // In caz de eroare terminate
while ((m_definitie[pozitie]=='-') || (m_definitie[pozitie]=='+'))
{
nod=new NOD;
nod->left=arb1;
nod->operatie=m_definitie[pozitie];
pozitie++;
arb2 = Termen();
nod->right=arb2;
if (arb2 == NULL)
{
Elibmem(nod);
return NULL;
}
arb1 = nod;
}
return arb1;
}
CExpressionBase::arbore CExpressionBase::Termen()
{
arbore nod;
arbore arb1 = Putere();
arbore arb2;
if(arb1 == NULL) return NULL; // In caz de eroare terminate
while ((m_definitie[pozitie]=='*') || (m_definitie[pozitie]=='/'))
{
nod=new NOD;
nod->left=arb1;
nod->operatie=m_definitie[pozitie];
pozitie++;
arb2 = Putere();
nod->right=arb2;
if(arb2 == NULL)
{
Elibmem(nod);
return NULL;
}
arb1 = nod;
}
return arb1;
}
CExpressionBase::arbore CExpressionBase::Putere()
{
arbore nod = NULL;
arbore arb1 = LogicalOp();
arbore arb2;
if(arb1 == NULL) return NULL;
while (m_definitie[pozitie]=='^')
{
nod=new NOD;
nod->left=arb1;
nod->operatie=m_definitie[pozitie];
pozitie++;
arb2 = LogicalOp();
nod->right=arb2;
if (arb2 == NULL)
{
Elibmem(nod);
return NULL;
}
arb1 = nod;
}
return arb1;
}
///////////////////////////////////////////////////////////////////////
// the new inserted operations logical operations on the first level of priority
// warning: for operations with more than one character you need to modify sligthly the code
// See also the new inserted operations in the vexp function
CExpressionBase::arbore CExpressionBase::LogicalOp()
{
arbore nod;
arbore arb1 = sgOp();
arbore arb2;
if (arb1 == NULL) return NULL;
while((m_definitie[pozitie]=='<') || (m_definitie[pozitie]=='>') /* || another same priority operations*/)
{
nod=new NOD;
nod->left=arb1;
nod->operatie=m_definitie[pozitie];
pozitie++;
arb2 = sgOp();
nod->right=arb2;
if(arb2 == NULL)
{
Elibmem(nod);
return NULL;
}
arb1 = nod;
}
return arb1;
}
CExpressionBase::arbore CExpressionBase::sgOp()
{
arbore nod = NULL;
arbore arb2;
if ((m_definitie[pozitie]=='!') /* || another same priority operations*/)
{
nod=new NOD;
nod->left=NULL;
nod->operatie=m_definitie[pozitie];
pozitie++;
arb2 = sgOp();
nod->right=arb2;
if (arb2 == NULL)
{
Elibmem(nod);
return NULL; // In caz de eroare terminate
}
}
else nod = Factor();
return nod;
}
CExpressionBase::arbore CExpressionBase::Factor()
{
arbore nod = NULL,nod2 = NULL,left = NULL;
while(m_definitie[pozitie] == ' ' && m_definitie[pozitie] != '\0')
pozitie++;
if (m_definitie[pozitie]=='-')
{
nod = new NOD;
left = new NOD;
left->right=NULL;
left->left=NULL;
left->operatie='@';
left->valoare=-1;
nod->left=left;
nod->operatie='*';
pozitie++;
nod->right = Expresie();
if (nod->right == NULL) return NULL;
return nod;
}
if (m_definitie[pozitie]=='(')
{
pozitie++;
nod = Expresie();
if (nod == NULL) return NULL;
if (m_definitie[pozitie]!=')')
{
Elibmem(nod);
return NULL;
}
pozitie++;
return nod;
}
else if (m_definitie[pozitie]=='|')
{
pozitie++;
nod2 = Expresie();
if (nod2 == NULL) return NULL;
if (m_definitie[pozitie]!='|')
{
Elibmem(nod);
return NULL;
}
nod = new NOD;
nod->left=nod2;
nod->right=NULL;
nod->operatie='|';
pozitie++;
return nod;
}
else return Identificator();
return nod;
}
CExpressionBase::arbore CExpressionBase::Identificator()
{
int poz;
arbore nod = NULL,nod2 = NULL;
arbore result = NULL;
poz=pozitie;
SkipSpaces();
if(m_definitie[pozitie]=='\0') result = NULL;
if(isdigit(m_definitie[pozitie])) //is a decimal digit (0 – 9).
{
while((isdigit(m_definitie[pozitie]) || (m_definitie[pozitie]=='.')))
pozitie++;
nod = new NOD;
nod->left = NULL;
nod->right = NULL;
nod->operatie = '@';
nod->valoare = atof(m_definitie.Mid(poz,pozitie-poz));
result = nod;
}
if(isalpha(m_definitie[pozitie])) //within the ranges A – Z or a – z
{
while(isalnum(m_definitie[pozitie])) pozitie++;
CString id = m_definitie.Mid(poz,pozitie-poz);
CString nid = id;
id.MakeUpper();
if (id=="SIN") // Functia sin CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_SIN;
SkipSpaces();
return nod;
}
if (id=="COS") // Functia cos CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_COS;
SkipSpaces();
return nod;
}
if (id=="EXP") // Functia exp CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_EXP;
SkipSpaces();
return nod;
}
if (id=="SQRT") // Functia sqrt CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_SQRT;
SkipSpaces();
return nod;
}
if (id=="LOG") // Functia log CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_LOG;
SkipSpaces();
return nod;
}
if (id=="TG") // Functia tg CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_TAN;
SkipSpaces();
return nod;
}
if (id=="CTG") // Functia ctg CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_CTAN;
SkipSpaces();
return nod;
}
if (id=="ASIN") // Functia asin CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_ASIN;
SkipSpaces();
return nod;
}
if (id=="ACOS") // Functia acos CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_ACOS;
SkipSpaces();
return nod;
}
if (id=="ATG") // Functia atg CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_ATAN;
SkipSpaces();
return nod;
}
if (id=="FABS") // Functia fabs CString
{
nod2 = Factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=OPER_FABS;
SkipSpaces();
return nod;
}
//CValue *valoare;
//if (m_pVariabile->Lookup(nid,valoare)) //不进行变量判断,认为剩下的都是变量
{
nod = new NOD;
nod -> left = NULL;
nod -> right = NULL;
nod -> operatie = '`';
nod -> valoarestr = new CString(nid);
result = nod;
}
//else result = NULL;
}
SkipSpaces();
return result;
}
int CExpressionBase::ChangeExpression(CString & expresie)
{
m_definitie = expresie + '\0' + '\0';
return UpdateArbore();
}
int CExpressionBase::Value(double& valoare)
{
code=0;
if (m_Arbore == NULL) return -1;
valoare=vexp(m_Arbore);
return (code);
}
double CExpressionBase::vexp(arbore a)
{
double v;
if (a->operatie==NULL) {code=10;return 0;}
switch(a->operatie)
{
//一般运算符号
case '+' : return( vexp(a->left)+vexp(a->right) );
case '-' : return( vexp(a->left)-vexp(a->right) );
case '*' : return( vexp(a->left)*vexp(a->right) );
case '/' :
v=vexp(a->right);
if (v==0)
{
code=DIVISION_BY_0;
return -vexp(a->left)/0.001;
}
else return(vexp(a->left)/v);
//三角函数
case OPER_SIN : return sin(vexp(a->left)*PI/180);
case OPER_COS : return cos(vexp(a->left)*PI/180);
case OPER_TAN : return tan(vexp(a->left)*PI/180);
case OPER_CTAN : return 1/tan(vexp(a->left)*PI/180);
case OPER_ASIN : return asin(vexp(a->left))*180/PI;
case OPER_ACOS : return acos(vexp(a->left))*180/PI;
case OPER_ATAN : return atan(vexp(a->left))*180/PI;
//常用函数
case OPER_EXP: return exp(vexp(a->left)); //指数
case OPER_SQRT: //平方根
v=vexp(a->left);
if (v<0) {code=INVALID_DOMAIN;return 0;}
else return sqrt(v);
case OPER_LOG: //对数
v=vexp(a->left);
if (v<=0) {code=INVALID_DOMAIN;return 0;}
else return log(v);
case OPER_FABS: //绝对值
return fabs(vexp(a->left));
case '^': //次方
return pow(vexp(a->left),vexp(a->right));
//logical operations evaluation
case '<' : return vexp(a->left)<vexp(a->right);
case '>' : return vexp(a->left)>vexp(a->right);
case '!' : return !vexp(a->right);
case '@' : return a->valoare;//返回单个值
default ://设置变量值
{
if (m_pVariabile==NULL)
{
code=UNDEFINED_VARIABLE; return 0;
}
CValue *valoare;
//::AfxMessageBox(*(a->valoarestr));
if (!m_pVariabile->Lookup(*(a->valoarestr),valoare))
{
code=UNDEFINED_VARIABLE; return 0;
}
else return valoare->GetValue();
}
}
}
////////////////////////////////////////////////////////////////////////////
CExpressionBase::arbore CExpressionBase::GetArbore()
{
return m_Arbore;
}
CExpressionBase::arbore CExpressionBase::Clone(arbore arb)
{
if (arb == NULL) return NULL;
arbore clonArb = new NOD;
*clonArb = *arb;
clonArb->left = Clone(arb->left);
clonArb->right = Clone(arb->right);
return clonArb;
}
CExpressionBase::arbore CExpressionBase::CloneTree()
{
return Clone(m_Arbore);
}
CExpressionBase::CExpressionBase(CExpressionBase & expresie)
{
*this = expresie;
}
void CExpressionBase::AtachVariables(CMapVariabile * vars)
{
m_pVariabile = vars;
}
CExpressionBase& CExpressionBase::operator=(CExpressionBase &expr)
{
m_definitie = expr.m_definitie;
m_pVariabile = expr.m_pVariabile;
pozitie = 0;
m_Arbore = expr.CloneTree();
return *this;
}
void CExpressionBase::SkipSpaces()
{
while (m_definitie[pozitie]==' ' && m_definitie[pozitie]!='\0')
pozitie ++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -