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

📄 calc.cpp

📁 科思ERP部分源码及控件
💻 CPP
字号:
//---------------------------------------------------------------------------
#include "vcl.h"
#pragma hdrstop

#include "Calc.h"
#include "math.h"
//---------------------------------------------------------------------------

#pragma package(smart_init)
//---------------------------------------------------------------
//    TExpression
//--------------------------------------------------------------
void TExpression::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
//////////////////////////////////////////////////////////////////////

__fastcall TExpression::TExpression()
{
    m_Arbore = NULL;
    m_definitie = "";
    pozitie = 0;
}
__fastcall TExpression::~TExpression()
{
    elibmem(m_Arbore);
}

int TExpression::UpdateArbore()
{
    if(m_definitie.IsEmpty())
    	return 0;
    elibmem(m_Arbore); // Eliberarea memoriei ocupate de arbore
    m_Arbore = NULL;
    pozitie = 1;
    m_Arbore = expresie();
    if (m_definitie[pozitie]!='\0')
    {
    	elibmem(m_Arbore);
    	m_Arbore = NULL;
    }

    if (m_Arbore == NULL)
    	return pozitie;
    else
        return -1;
}

TExpression::arbore TExpression::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;
}

TExpression::arbore TExpression::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;
}

TExpression::arbore TExpression::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;
}

TExpression::arbore TExpression::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();
}

TExpression::arbore TExpression::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]))	// Este numar ?
   {
       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.SubString(poz,pozitie-poz).c_str());
       result = nod;
   }
   if (isalpha(m_definitie[pozitie]) ||
       m_definitie[pozitie] == '[' ||
       m_definitie[pozitie] == ']' ||
       m_definitie[pozitie] < 0)	// Am i an identifier ?
   {
       while(isalnum(m_definitie[pozitie]) ||
              m_definitie[pozitie] == '[' ||
              m_definitie[pozitie] == ']' ||
              m_definitie[pozitie] < 0)
           pozitie++;
   	AnsiString id = m_definitie.SubString(poz,pozitie-poz);
   	AnsiString nid = id;
   	id = id.UpperCase();

        if(id =="SIN")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=150;
		SkipSpaces();
		return nod;
	}
	if(id =="COS")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=151;
		SkipSpaces();
		return nod;
	}
	if(id =="EXP")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=152;
		SkipSpaces();
		return nod;
	}
	if(id =="SQRT")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=153;
		SkipSpaces();
		return  nod;
	}
	if(id =="LOG")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=154;
		SkipSpaces();
		return nod;
	}
	if(id =="TG")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=155;
		SkipSpaces();
		return nod;
	}
	if(id =="CTG")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=156;
		SkipSpaces();
		return nod;
	}
	if(id =="ASIN")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=157;
		SkipSpaces();
		return nod;
	}
	if(id =="ACOS")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right=NULL;
		nod->operatie=158;
		SkipSpaces();
		return nod;
	}
	if(id =="ATG")		// Functia sinus CString
	{
		nod2 = factor();
		nod = new NOD;
		nod->left = nod2;
		nod->right = NULL;
		nod->operatie = 159;
		SkipSpaces();
		return nod;
	}
	if(FIsVariable && FIsVariable(nid))
	{
		nod = new NOD;
		nod->left = NULL;
		nod->right = NULL;
		nod->operatie = '`';
		nod->valoarestr = new AnsiString(nid);
		result = nod;
	}else
		result = NULL;
	}
	SkipSpaces();
	return result;
}

int TExpression::ChangeExpression(AnsiString expresie)
{
	m_definitie = expresie + '\0' + '\0';
	return UpdateArbore();
}

int TExpression::Value(double& valoare)
{
  code=0;
  if (m_Arbore == NULL) return -1;
  valoare=vexp(m_Arbore);
  return (code);
}

double TExpression::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 150 :
           return(sin(vexp(a->left)));
       case 151 :
           return(cos(vexp(a->left)));
       case 152 :
           return(exp(vexp(a->left)));
       case 153 :
           v=vexp(a->left) ;
	   if(v<0)
           {
              code=INVALID_DOMAIN;
              return 0;
           }else
              return(sqrt(v));
       case 154 :
           v=vexp(a->left) ;
	   if(v<=0)
           {
              code=INVALID_DOMAIN;
              return 0;
           }else
              return(log(v));
       case 155 :
           return (tan (vexp(a->left)));
       case 156 :
           return (1 / tan (vexp(a->left)));
       case 157 :
           return (asin (vexp(a->left)));
       case 158 :
           return (acos (vexp(a->left)));
       case 159 :
           return (atan (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:
       {
	   if (FIsVariable == NULL)
	   {
	   	code=UNDEFINED_VARIABLE;
	   	return 0;
	   }
	   if (!FIsVariable(*a->valoarestr))
	   {
	   	code=UNDEFINED_VARIABLE;
	   	return 0;
	   }else
	   	return FGetValue(*a->valoarestr);
       }
   }
}

TExpression::arbore TExpression::GetArbore()
{
   return m_Arbore;
}

TExpression::TExpression(TExpression & expresie)
{
   *this = expresie;
}

TExpression::arbore TExpression::CloneTree()
{
   return clone(m_Arbore);
}

TExpression::arbore TExpression::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;
}

TExpression& TExpression::operator=(TExpression &expr)
{
   m_definitie = expr.m_definitie;
   pozitie = 0;
   m_Arbore = expr.CloneTree();
   return *this;
}

void TExpression::SkipSpaces()
{
   while (m_definitie[pozitie]==' ' && 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
TExpression::arbore TExpression::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;
}

TExpression::arbore TExpression::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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -