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

📄 strtooper.cpp

📁 数字信号处理实验程序。福利业快速变换
💻 CPP
字号:
//
// StrToOper.cpp: Change a CSting to operation and calculate it
//copyright @ luda				lartely@163.com
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "StrToOper.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

void CStrToOper::Clear(void)
{
	ErrId=0;
	Expression="";
	Result=0.0;
	x=0.0;
}

void CStrToOper::Initial(CString operation,double input)
{	ErrId=0;
	Result=0.0;
	int i;
	Expression=operation;
	x=input;
	CString unilligel=" _[]!@#$%&|\';:<>,?";
		for (i=0;i<unilligel.GetLength();i++)
	Expression.Remove(unilligel.GetAt(i));//去除非法的字符
	CString strPI,strX;
	strX.Format("%4.6f",x);
	Expression.Replace("exp","EXP");
	Expression.Replace("x",strX);
	strPI.Format("%4.6f",3.1415926);
	Expression.Replace("pi",strPI);
	Expression.MakeLower();
	ErrCheck();
}

void CStrToOper::ErrCheck(void)
{
	int leftParenthese=0,rightParenthese=0;
	int i;
	for (i=0;i<Expression.GetLength();i++)
	{
		if (Expression.GetAt(i)=='(')
			leftParenthese++;
		if (Expression.GetAt(i)==')')
			rightParenthese++;
	}
	if (leftParenthese<rightParenthese)
	{
		ErrId=ERR_MISSLEFTPARA;
		return;
	}
	if (leftParenthese>rightParenthese)
	{
		ErrId=ERR_MISSRIGHTPARA;
		return;
	}

}

const CString CStrToOper::GetErrMsg(void)
{
	static const CString errmsg[7] = {"no errors",
		"missing left parentheses",
		"missing right parentheses",
		"devide by zero",
		"unknown operator",
		"unknown error",
		"UNKNOWN ERROR ID"};
	if(ErrId >= 0 && ErrId < 6)
		return errmsg[ErrId];
	else
		return errmsg[6];
}

int CStrToOper::GetErrId(void)
{
	return ErrId;
}

double CStrToOper::Calculate(int type, double x, double y)
{ // 双目运算符的具体运算
    
	if (type > 20 && type < 40) //处理双目运算
   		switch(type)  { // '+' , '-' , '*' , '/' , '^'
   		case OPTR_ADD : return ( x + y ); 
   		case OPTR_SUBTRACT : return ( x - y ); 
   		case OPTR_MULTIPLY : return ( x * y ); 
   		case OPTR_DIVIDE : 
			if (y == 0.0) 
				ErrId=ERR_DIVIDEBYZERO;
   			else
				return ( x / y );
    		break;
		case OPTR_POWER : return (pow( x, y));
		default : ErrId=ERR_UNKNOWNOPR; return 0.0;
		}
    else {
		ErrId=ERR_UNKNOWNOPR; 
		return 0.0;
    }
	return 0.0;
}

double CStrToOper::Calculate(int type, double x)
{// 单目运算符的具体运算
    static double (*fun[])(double)={sin, cos, tan, sqrt, 
		log10, log, fabs, asin, acos, atan, sinh,
		cosh, tanh, exp}; //*fname[]对应的C函数名

		if(type>50) //函数运算
			return ((*fun[type-51])(x));
		else {
			ErrId=ERR_UNKNOWNOPR; 
			return 0.0;
		}
	
	return 0.0;
}

bool CStrToOper::IsNum(CString str,int thisposition)
{
	if (isdigit(str.GetAt(thisposition))||(str.GetAt(thisposition)=='.')||(str.GetAt(thisposition)=='-')&&(!isdigit(str.GetAt(thisposition-1))))
		return TRUE;
	else return FALSE;
}
int CStrToOper::GetPreValue(CString str,int position,CString &str1)
{	
	int thisposition;
	thisposition=position-1;
	while (thisposition>0&&IsNum(str,thisposition))
	{
			thisposition--;
	}
	if (thisposition!=0) 
		thisposition++;
	str1=str.Mid(thisposition,position-thisposition);
    
return thisposition;
}

int CStrToOper::GetNextValue(CString str,int position,CString &str2)
{
	int thisposition=position+1;
   while (IsNum(str,thisposition)&&thisposition<str.GetLength()-1)
   {
	   thisposition++;
   }
   if (thisposition!=str.GetLength()-1) 
	   thisposition--;
   str2=str.Mid(position+1,thisposition-position);
   return thisposition;
}
double CStrToOper::ValueCalculate(CString str)//对只有数值和操作符的表达式进行计算
{
	int flag=1;
	int i;
	int position;
	int position1;
	int position2;
	int preposition;
	int nextposition;
	int OPTR_SELECT;
	double tempresult;
	CString str1;
	CString str2;
	CString strpre,strmid,strnext;
	flag=(str.Find('^')!=-1);
   while (flag)									//处理最高级别^
   {  
	   position=str.Find('^');
	   preposition=GetPreValue(str,position,str1);
	   nextposition=GetNextValue(str,position,str2);
	   tempresult=Calculate(OPTR_POWER,atof(str1),atof(str2));
	   strpre=str.Left(preposition);
	   strmid.Format("%4.6f",tempresult);
	   strnext=str.Right(str.GetLength()-nextposition-1);
	   str=strpre+strmid+strnext;
	   flag=(str.Find('^')!=-1);
   }
	   
	flag=((str.Find('*')!=-1)||(str.Find('/')!=-1));
   while (flag)									//处理次高级别*,/
   {   position1=str.Find('*');
	   position2=str.Find('/');
	   if (((position1<position2)&&(position1!=-1))||(position2==-1))
	   {
		   position=position1;
		   OPTR_SELECT=OPTR_MULTIPLY;
	   }
	   else
	   {
		   position=position2;
		   OPTR_SELECT=OPTR_DIVIDE;
	   }
	   preposition=GetPreValue(str,position,str1);
	   nextposition=GetNextValue(str,position,str2);
	   tempresult=Calculate(OPTR_SELECT,atof(str1),atof(str2));
	   strpre=str.Left(preposition);
	   strmid.Format("%4.6f",tempresult);
	   strnext=str.Right(str.GetLength()-nextposition-1);	 
	   str=strpre+strmid+strnext;
	   flag=((str.Find('*')!=-1)||(str.Find('/')!=-1));
   }

   	flag=((str.Find('+')!=-1)||(str.Find('-',1)!=-1));
	i=0;
   while (flag)									//处理低级别+,-
   {   
	   position1=str.Find('+');
	   position2=str.Find('-',1);
	   i=position2+1;
	   if (((position1<position2)&&(position1!=-1))||(position2==-1))
	   {
		   position=position1;
		   OPTR_SELECT=OPTR_ADD;
	   }
	   else
	   {
		    position=position2;
			OPTR_SELECT=OPTR_SUBTRACT;
		}
	   preposition=GetPreValue(str,position,str1);
	   nextposition=GetNextValue(str,position,str2);
	   tempresult=Calculate(OPTR_SELECT,atof(str1),atof(str2));
	   strpre=str.Left(preposition);
	   strmid.Format("%4.6f",tempresult);
	   strnext=str.Right(str.GetLength()-nextposition-1);
	   str=strpre+strmid+strnext;
	   flag=(str.Find('+')!=-1)||(str.Find('-',1)!=-1);
   }
   tempresult=atof(str);
   return tempresult;
}


BOOL CStrToOper::GetOperType(CString str,int leftParentese,int &count,int &type)
{	type=0;
	count=3;		//操作符长度
	CString strOpr;
	while (count<6)
	{
		if (leftParentese-count<0) return FALSE;
		else  
		{	strOpr=str.Mid(leftParentese-count,count);
			
			if (strOpr=="sin")type=51;
			if (strOpr=="cos")type=52;
			if (strOpr=="tan")type=53;
			if (strOpr=="sqrt")type=54;
			if (strOpr=="log10")type=55;
			if (strOpr=="log")type=56;
			if (strOpr=="fabs")type=57;
			if (strOpr=="asin")type=58;
			if (strOpr=="acos")type=59;
			if (strOpr=="atan")type=60;
			if (strOpr=="sinh")type=61;
			if (strOpr=="cosh")type=62;
			if (strOpr=="tanh")type=63;
			if (strOpr=="exp")type=64;
			if (type!=0) return TRUE;
				
		}
		count++;
	}
	return FALSE;
}

CString CStrToOper::RemoveParentheses()				//将表达式变成数值表达式
{
	int flag,count=0,type;
	int leftParenthese,rightParenthese;
	CString str=Expression;
	CString strpre,strmid,strnext;
	flag=(str.Find(')')!=-1);
	while (flag)
	{
		rightParenthese=str.Find(')');
		leftParenthese=rightParenthese-1;
		while (str.GetAt(leftParenthese)!='(')
		{
			leftParenthese--;
		}
		if (leftParenthese==0||!isalnum(str.GetAt(leftParenthese-1)))
		{
			strpre=str.Left(leftParenthese);
			strmid.Format("%4.6f",ValueCalculate(str.Mid(leftParenthese+1,rightParenthese-leftParenthese-1)));
			strnext=str.Right(str.GetLength()-rightParenthese-1);
		}
		else 
		{
			if (GetOperType(str,leftParenthese,count,type))
			{
				strpre=str.Left(leftParenthese-count);
				strmid.Format("%4.6f",Calculate(type,ValueCalculate(str.Mid(leftParenthese+1,rightParenthese-leftParenthese-1))));
				strnext=str.Right(str.GetLength()-rightParenthese-1);
			}
			else
			{
				ErrId=ERR_UNKNOWNOPR;
				break;
			}
		}
		str=strpre+strmid+strnext;
		flag=(str.Find(')')!=-1);
	}
	return str;
}

void CStrToOper::Computer()
{   CString strValue;
	strValue=RemoveParentheses();                    
	Result=ValueCalculate(strValue);
}

double CStrToOper::GetResult(void)
{	if (ErrId==0)
	Computer();
	return Result;
}

CStrToOper::~CStrToOper()
{

}

⌨️ 快捷键说明

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