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

📄 ccalexpression.h

📁 字符串计算公式
💻 H
字号:
#include "tsStack.h"
#include <math.h>

/*
    该类用于求字符型数值表达式
	要扩展函数请在Extend_Func函数中依照已有数学函数格式添加
*/

/*

//类CCalExpression用法
//实例化
CCalExpression myCalExpression;
//设置要计算的表达式,m_EditExpression为CString类型
myCalExpression.SetExpression(m_EditExpression);
//计算该表达式,表达式输入有错返回FALSE 成功返回TRUE
if(myCalExpression.CalculateResult())
{
    //myCalExpression.GetStrResult()得到计算结果 CString类型
    //GetNumResult()方法得到Double类型的数值结果
	m_StaticResult.SetWindowText(myCalExpression.GetStrResult());
	
}
*/
class CCalExpression  
{
public:
	BOOL CalculateResult();
	void SetExpression(CString StrExpression);
	double GetNumResult();
	CString GetStrResult();

	CCalExpression(CString StrExpression);
	CCalExpression();
	virtual ~CCalExpression();

	
private:
	BOOL IsNumberic(char* oText);
	BOOL StrRead(char* StrExp,int* ipos, char* opstr);

	char Precede(char* stackopr,char* c);

	double Operate(double a, char* theta, double b);

	BOOL IsNumchar(char c);
	BOOL IsABCchar(char c);

	BOOL Extend_Func(char* op,char* num);

	int getPRI_1(char* optr);
	int getPRI_2(char* optr);

	BOOL IsOprater(char c);
	CString _StrResult;
	double _NumResult;
	CString _StrExpression;

	char opstr[10];
};

CCalExpression::CCalExpression()
{
}

CCalExpression::~CCalExpression()
{
}

CString CCalExpression::GetStrResult()
{
	return _StrResult;
	
}

double CCalExpression::GetNumResult()
{
	return _NumResult;
	
}

void CCalExpression::SetExpression(CString StrExpression)
{
	StrExpression.MakeUpper();
	_StrExpression = StrExpression;
	_StrExpression.Insert(_StrExpression.GetLength(),'#');
	//_StrResult=_StrExpression;
}

CCalExpression::CCalExpression(CString StrExpression)
{
	StrExpression.MakeUpper();
	_StrExpression = StrExpression;
	_StrExpression.Insert(_StrExpression.GetLength(),'#');
}

BOOL CCalExpression::CalculateResult()
{	
	Stack<char*>OPTRStack;
	Stack<double>OPNDStack;
	char c[20];
	char temp[50][20];
	int n_optr = 0;

	char strexpres[100];
	strcpy(strexpres,_StrExpression);
	int ipos=0;
	OPTRStack.push("#");
	if(!StrRead(strexpres,&ipos,c)) return FALSE;
	while(strcmp(c,"#") !=0 || strcmp(OPTRStack.GetTop() , "#")!= 0 )
	{
		if(IsNumberic(c))
		{
			OPNDStack.push(atof(c));
			if(!StrRead(strexpres,&ipos,c)) return FALSE;
		}
		else if((strcmp(c,"-") == 0 || strcmp(c,"+") == 0) 
			&& strcmp(OPTRStack.GetTop(),"(") == 0 )
		{
			OPNDStack.push(0);
			strcpy(temp[n_optr],c);
			OPTRStack.push(temp[n_optr]);
			n_optr++;
			if(!StrRead(strexpres,&ipos,c)) return FALSE;	
		}
		else
		{
			if(getPRI_1(c) == -1) return FALSE;
			switch(Precede(OPTRStack.GetTop(),c))
			{
			case '<':
				strcpy(temp[n_optr],c);
				OPTRStack.push(temp[n_optr]);
				n_optr++;
				if(!StrRead(strexpres,&ipos,c)) return FALSE;
				break;
			case '=':
				strcpy(c,OPTRStack.pop());
				if(!StrRead(strexpres,&ipos,c)) return FALSE;
				break;
			case '>':
				char theta[20];
				double a,b;
				b = OPNDStack.pop();
				a = OPNDStack.pop();
				strcpy(theta,OPTRStack.pop());
				OPNDStack.push(Operate(a,theta,b));
				break;
			}
		}
	}
	_NumResult = OPNDStack.GetTop();
	_StrResult.Format("%f", _NumResult);

	return TRUE;
}

double CCalExpression::Operate(double a, char* theta, double b)
{
	if(strcmp(theta,"+") == 0)return a+b;
	else if(strcmp(theta,"-") == 0)return a-b;
	else if(strcmp(theta,"*") == 0)return a*b;
	else if(strcmp(theta,"/") == 0)return a/b;
	else return -1;
}

char CCalExpression::Precede(char* stackopr,char* c)
{
	if(getPRI_1(stackopr) > getPRI_2(c)) return '>';
	else if(getPRI_1(stackopr) == getPRI_2(c)) return '=';
	else  return '<';
}

int CCalExpression::getPRI_1(char* optr)
{
	if     (strcmp(optr,"+") == 0)return 11;
	else if(strcmp(optr,"-") == 0)return 11;
	else if(strcmp(optr,"*") == 0)return 14;
	else if(strcmp(optr,"/") == 0)return 14;
	else if(strcmp(optr,"(") == 0)return 8;
	else if(strcmp(optr,")") == 0)return 20;
	else if(strcmp(optr,"#") == 0)return 3;
	else return -1;
}

int CCalExpression::getPRI_2(char* optr)
{
	if     (strcmp(optr,"+") == 0)return 10;
	else if(strcmp(optr,"-") == 0)return 10;
	else if(strcmp(optr,"*") == 0)return 13;
	else if(strcmp(optr,"/") == 0)return 13;
	else if(strcmp(optr,"(") == 0)return 20;
	else if(strcmp(optr,")") == 0)return 8;
	else if(strcmp(optr,"#") == 0)return 3;
	else return -1;
}


BOOL CCalExpression::StrRead(char* StrExp,int* ipos, char* c)
{

	char c_current;
	c_current= StrExp[*ipos];
	while(c_current == 32)
	{
		(*ipos)++;
		c_current= StrExp[*ipos];
	}
	if(IsNumchar(c_current))
	{
		int i_end = 1;
		opstr[i_end-1]=StrExp[*ipos];
		opstr[i_end]='\0';
		for( int n=(*ipos+1); IsNumberic(opstr);n++)
		{
			i_end++;
			opstr[i_end-1]=StrExp[n];
			opstr[i_end]='\0';
		}
		opstr[i_end-1]='\0';
		(*ipos) = n-1;
	    strcpy(c, opstr);
		return TRUE;
	}
	else if(c_current == ')' || c_current == '(')
	{
		opstr[0] = c_current;
		opstr[1] = '\0';
		(*ipos)++;
		strcpy(c, opstr);
		return TRUE;
	}

	else if(IsABCchar(c_current))
	{
		int i_end = 1;
		opstr[i_end-1]=StrExp[*ipos];
		opstr[i_end]='\0';
		for( int n=(*ipos+1); IsABCchar(c_current); n++)
		{
			i_end++;
			c_current= StrExp[n];
			opstr[i_end-1]=StrExp[n];
		}
		if(i_end!=1)
		{
			opstr[i_end-1]='\0';
			*ipos = n-1;
		}
		else opstr[i_end]='\0';
		char temp_opn[20];
		
		if(StrExp[*ipos] != '(') return FALSE;
		else
		{
			(*ipos)++;

			int i_end = 1;
			temp_opn[i_end-1]=StrExp[*ipos];
			temp_opn[i_end]='\0';
			for( int n=(*ipos+1); IsNumberic(temp_opn);n++)
			{
				i_end++;
				temp_opn[i_end-1]=StrExp[n];
				temp_opn[i_end]='\0';
			}
			temp_opn[i_end-1]='\0';
			(*ipos) = n-1;
			
			if(!IsNumberic(temp_opn)) return FALSE;
			if(StrExp[*ipos] != ')') return FALSE;
			if(!Extend_Func(opstr,temp_opn))return FALSE;
			(*ipos)++;
			strcpy(c,temp_opn);
		}	
		return TRUE;
	}

	else
	{
		int i_end = 1;
		opstr[i_end-1]=StrExp[*ipos];
		opstr[i_end]='\0';
		for( int n=(*ipos+1); IsOprater(c_current); n++) //!IsNumchar(c_current) && !IsABCchar(c_current) && strcmp(opstr,"#") !=0 && c_current !='(' ; n++)
		{
			i_end++;
			c_current= StrExp[n];
			opstr[i_end-1]=StrExp[n];
		}
		if(i_end!=1)
		{
			opstr[i_end-1]='\0';
			*ipos = n-1;
		}
			else opstr[i_end]='\0';
		
		strcpy(c, opstr);
		return TRUE;
	}
}

BOOL CCalExpression::Extend_Func(char* op,char* num )
{
	CString temp;
	double fun_result;
	if(strcmp(op,"SIN") == 0)
		fun_result = sin(atof(num));
	else if(strcmp(op,"COS") == 0)
		fun_result = cos(atof(num));
	else if(strcmp(op,"SQRT") == 0)
		fun_result = sqrt(atof(num));
	else return FALSE;

	temp.Format("%.7f",fun_result);
	strcpy(num,temp);
	return TRUE;
}

BOOL CCalExpression::IsOprater(char c)
{
	if(strcmp(opstr,"+") ==0 ||
	   strcmp(opstr,"-") ==0 ||
	   strcmp(opstr,"*") ==0 ||
	   strcmp(opstr,"/") ==0
		)return TRUE;
	else return FALSE;
}

BOOL CCalExpression::IsNumchar(char c)
{
	if((c >='0' && c <= '9') || c == '.')
	{
		return TRUE;
	}
		
	else
	{
		return FALSE;
	}
		

}

BOOL CCalExpression::IsABCchar(char c)
{
	if(c > 'A' && c < 'Z')
	{
		return TRUE;
	}
	else 
	{
		return FALSE;
	}
	
}

BOOL CCalExpression::IsNumberic(char* oText)
{
   if(strcmp(oText,"-") == 0)return FALSE;
   if(strcmp(oText,".") == 0)return FALSE;
   
   for(int i=0; oText[i] != '\0' ;i++)
   {
	   if(i==0 && oText[i]=='-') break;
	   if(!IsNumchar(oText[i]))return FALSE;
   }
   return TRUE;
}


⌨️ 快捷键说明

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