📄 express.cpp
字号:
// Function.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "math.h"
#include "express.h"
#include "resource.h"
#include <ctype.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CExpression, CObject, 0)
//////////////////////////////////////////////////////////////////////
// CExpression Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Variabile Globale
//parametrii Global(50);
/////////////////////////////////////////////////////////////////////////////////
// Eliberarea memorie ocupate de arbore
void CExpression::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;
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CExpression::CExpression()
{
m_Arbore = NULL;
m_definitie = "";
pozitie = 0;
NumOfVar=0;
}
CExpression::~CExpression()
{
elibmem (m_Arbore);
}
void CExpression::Serialize(CArchive & ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
ar << m_definitie;
}
else
{
// TODO: add loading code here
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
}
}
int CExpression::UpdateArbore()
{
if (m_definitie.IsEmpty())
return 0;
elibmem(m_Arbore); // Eliberarea memoriei ocupate de arbore
m_Arbore = NULL;
pozitie = 0;
m_Arbore = expresie();
SkipSpaces();
if (m_definitie[pozitie]!='\0')
{
elibmem(m_Arbore);
m_Arbore = NULL;
}
if (m_Arbore == NULL)
return pozitie;
else return -1;
}
CExpression::arbore CExpression::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; // In caz de eroare terminate
}
arb1 = nod;
}
return arb1;
}
CExpression::arbore CExpression::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; // In caz de eroare terminate
}
arb1 = nod;
}
return arb1;
}
CExpression::arbore CExpression::putere()
{
arbore nod = NULL;
arbore arb1 = logicalOp();
arbore arb2;
if (arb1 == NULL) return NULL; // In caz de eroare terminate
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; // In caz de eroare terminate
}
arb1 = nod;
}
return arb1;
}
CExpression::arbore CExpression::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;
}
CExpression::arbore CExpression::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 it a number?
{
BOOL digitf=TRUE;
while (digitf)
{
if((isdigit(m_definitie[pozitie]) || (m_definitie[pozitie]=='.')))
{
pozitie++;
digitf=TRUE;
}else if((m_definitie[pozitie]=='E')||(m_definitie[pozitie]=='e'))
{
pozitie++;
digitf=TRUE;
if((m_definitie[pozitie]=='+')||(m_definitie[pozitie]=='-')||(isdigit(m_definitie[pozitie])))
{
pozitie++;
}
}else
{
digitf=FALSE;
}
}
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])) // Am i an identifier ?
{
while (isalnum(m_definitie[pozitie]))
pozitie++;
CString id = m_definitie.Mid(poz,pozitie-poz);
CString nid = id;
id.MakeUpper();
if (id =="SIN") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_SIN;
SkipSpaces();
return nod;
}
if (id =="COS") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_COS;
SkipSpaces();
return nod;
}
if (id =="EXP") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_EXP;
SkipSpaces();
return nod;
}
if (id =="SQRT") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_SQRT;
SkipSpaces();
return nod;
}
if (id =="LOG") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_LOG;
SkipSpaces();
return nod;
}
if (id =="TG") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_TG;
SkipSpaces();
return nod;
}
if (id =="CTG") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_CTG;
SkipSpaces();
return nod;
}
if (id =="ASIN") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_ASIN;
SkipSpaces();
return nod;
}
if (id =="ACOS") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_ACOS;
SkipSpaces();
return nod;
}
if (id =="ATG") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_ATG;
SkipSpaces();
return nod;
}
if (id =="SINH") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_SINH;
SkipSpaces();
return nod;
}
if (id =="COSH") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_COSH;
SkipSpaces();
return nod;
}
if (id =="ASINH") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_ASINH;
SkipSpaces();
return nod;
}
if (id =="ACOSH") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_ACOSH;
SkipSpaces();
return nod;
}
if (id =="ABS") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_ABS;
SkipSpaces();
return nod;
}
if (id =="LOG10") // Functia sinus CString
{
nod2 = factor();
nod = new NOD;
nod->left = nod2;
nod->right=NULL;
nod->operatie=F_LOG10;
SkipSpaces();
return nod;
}
// double* valuet=GetVarVal(nid);
// if (valuet!=NULL)
{
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 CExpression::ChangeExpression(CString & expresie)
{
m_definitie = expresie + '\0' + '\0';
return UpdateArbore();
}
// Error code var
int code;
int CExpression::Value(double& valoare)
{
code=0;
if (m_Arbore == NULL) return -1;
valoare=vexp(m_Arbore);
return (code);
}
double CExpression::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 F_SIN : return(sin(vexp(a->left)));
case F_COS : return(cos(vexp(a->left)));
case F_EXP : return(exp(vexp(a->left)));
case F_SQRT : v=vexp(a->left) ;
if (v<0) {code=INVALID_DOMAIN;return 0;}
else return(sqrt(v));
case F_LOG : v=vexp(a->left) ;
if (v<=0) {code=INVALID_DOMAIN;return 0;}
else return(log(v));
case F_TG : return (tan (vexp(a->left)));
case F_CTG : return (1 / tan (vexp(a->left)));
case F_ASIN : return (asin (vexp(a->left)));
case F_ACOS : return (acos (vexp(a->left)));
case F_ATG : return (atan (vexp(a->left)));
case F_SINH :
{
double x=(vexp(a->left));
return (exp(x)-exp(-x))/2.0;
}
case F_COSH :
{
double x=(vexp(a->left));
return (exp(x)+exp(-x))/2.0;
}
case F_ASINH :
{
double x=(vexp(a->left));
return (log(x+sqrt(x*x+1)));
}
case F_ACOSH :
{
double x=(vexp(a->left));
if(x>=1)
{
return (log(x+sqrt(x*x-1)));
}else
{
code=INVALID_DOMAIN;
return 0;
}
}
case F_ABS : return (fabs(vexp(a->left)));
case F_LOG10 : return (log10(vexp(a->left)));
case '|' : return(fabs(vexp(a->left)));
case '^' : return(pow(vexp(a->left),vexp(a->right)));
case '@' : return (a->valoare);
//logical operations evaluation
case '<' : return( vexp(a->left)<vexp(a->right) );
case '>' : return( vexp(a->left)>vexp(a->right) );
case '!' : return(!vexp(a->right)) ;
default : {
CString nid=*a->valoarestr;
double* valuet=GetVarVal(nid);
if (valuet==NULL)
{
code=UNDEFINED_VARIABLE;
return 0;
}
else
return *valuet;
}
}
}
CExpression::arbore CExpression::GetArbore()
{
return m_Arbore;
}
CExpression::CExpression(CExpression & expresie)
{
*this = expresie;
}
CExpression::arbore CExpression::CloneTree()
{
return clone(m_Arbore);
}
CExpression::arbore CExpression::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;
}
CExpression& CExpression::operator=(CExpression &expr)
{
m_definitie = expr.m_definitie;
pozitie = 0;
m_Arbore = expr.CloneTree();
return *this;
}
void CExpression::SkipSpaces()
{
while ((m_definitie[pozitie]==' '||m_definitie[pozitie]==0x0a||m_definitie[pozitie]==0x0d) && m_definitie[pozitie]!='\0')
pozitie ++;
}
///////////////////////////////////////////////////////////////////////
// the new inserted operations
// logical operations on the first level of priority
// warning: for operations with more than one character you nedd to modify sligthly the code
// See also the new inserted operations in the vexp function
CExpression::arbore CExpression::logicalOp()
{
arbore nod;
arbore arb1 = sgOp();
arbore arb2;
if (arb1 == NULL) return NULL; // In caz de eroare terminate
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; // In caz de eroare terminate
}
arb1 = nod;
}
return arb1;
}
CExpression::arbore CExpression::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;
}
void CExpression::SetVarValue(CString* names, double* values, int num)
{
VarNames=names;
VarValues=values;
NumOfVar=num;
}
double *CExpression::GetVarVal(CString & name)
{
for(int i=0;i<NumOfVar;i++)
{
if(name==VarNames[i])
{
return (&VarValues[i]);
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -