📄 ccalexpression.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 + -