⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expressionbase.cpp

📁 输入一个公式
💻 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 + -