📄 stringresolution.cpp
字号:
// StringResolution.cpp: implementation of the CStringResolution class.
/***********************************************************************************************
* Copyright (c) Zhou Yuncai(周云才 江汉石油学院计算机系),2002
* All rights reserved EXCEPT as allow by the following statements:
* You can freely use this file for your own work (personal or commercial).
* But,you cannot remove this copyright and notice.
* You cannot distribute modified versions of the source code in this package.
* You cannot use this file in printed media without the express permission of the author.
* Zhou Yuncai makes no representation about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty of any kind, including any implied
* warranty of merchantability, fitness for a particular purpose, or non-infringement.
* The entire risk as to the quality and performance of the software is with you.
* Zhou Yuncai shall not be liable for any damages suffered by you or any third party as a result of
* using or distributing this software.
* In no event will Zhou Yuncai be liable for any lost revenue, profit, or data, or for direct,
* indirect, special, consequential, incidental, or punitive damages, however caused and regardless of
* the theory of liability, arising out of the use of or inability to use software, even if Zhou Yuncai
* has been advised of the possibility of such damages.
* Should the software prove defective, you assume the cost of all necessary servicing, repair,
* or correction. If you think you've found an error, please e-mail the correction using the
* form you will find to zyc262@163.net
* address:湖北省荆州市江汉石油学院计算机系
**********************************************************************************************/
#include "stdafx.h"
#include "StringResolution.h"
#include <math.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#ifdef _ERROR_INFO_H_
BEGIN_CATCH_MATH_ERROR
_BEGIN_GET_TYPE
GET_ERROR_TYPE(_DOMAIN,BIGNUMBER,Argument domain error.)
GET_ERROR_TYPE(_SING,BIGNUMBER,Argument singularity.)
GET_ERROR_TYPE(_OVERFLOW,BIGNUMBER,Overflow range error.)
GET_ERROR_TYPE(_UNDERFLOW,0,Underflow range error.)
GET_ERROR_TYPE(_TLOSS,0,Total loss of precision.)
GET_ERROR_TYPE(_PLOSS,0,Partial loss of precision.)
_END_GET_TYPE
GET_ERROR_FUNCTION(pow,power function exception. )
GET_ERROR_FUNCTION(tan,tangent function exception. )
GET_ERROR_FUNCTION(asin,arcsine function exception. )
GET_ERROR_FUNCTION(acos,arccosine function exception. )
END_CATCH_MATH_ERROR
IMPLEMENT_CATCH_ERROR(CStringResolution)
#endif
CStringResolution::CStringResolution(char*formula)
:m_oprandNum(0),m_oprandANum(0),m_operatorNum(0)
{
m_operator=0;
m_oprand=0;
m_oprandA=0;
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(0,FALSE,"Good");
#endif
if(formula)
{
m_formula=formula;
Initialize();
}
}
CStringResolution::~CStringResolution()
{
if(m_operator)
delete[]m_operator;
if(m_oprand)
delete[]m_oprand;
if(m_oprandA)
delete[]m_oprandA;
}
void CStringResolution::SetFormula(char *formula)
{
if(!formula)
return;
m_formula=formula;
if(m_operator)
{
delete[]m_operator;
m_operator=0;
}
if(m_oprand)
{
delete[]m_oprand;
m_oprand=0;
}
if(m_oprandA)
{
delete[]m_oprandA;
m_oprandA=0;
}
m_oprandNum=0,m_oprandANum=0,m_operatorNum=0;
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(0,FALSE,"Good!");
#endif
Initialize();
}
int CStringResolution::IsFormula()
{
int bRet=0;
stack<char> charStack;
int i,num=m_formula.GetLength();
char notChar[]={';','\'',':',' ','[',']','{','}','\\','|',',','\"','=','&','%','$','@','#','!','`','~','?'};
int notNum=sizeof notChar;
for(i=0;i<num;i++)
{
for(int j=0;j<notNum;j++)
{
if(m_formula[i]==notChar[j])
{
CString s;
s.Format("The %dth character,\"%c\" is invalidated!",i+1,m_formula[i]);
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(-i-1,TRUE,s);
#endif
return -i-1;//the ith symbol is invalidating.
}
}
}
for(i=0;i<num;i++)
{
if(m_formula[i]=='(')
charStack.push('(');
if(m_formula[i]==')')
{
if(charStack.empty())
{
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(1,TRUE,"There are some more right brackets!");
#endif
return 1;//right bracket if more.
}
else
charStack.pop();
}
}
if(!charStack.empty())
{
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(2,TRUE,"There are some more left brackets!");
#endif
return 2;//left bracket is more.
}
return bRet;
}
BOOL CStringResolution::GetStack(OperatorStack &Operator, OperandStack &Oprand)
{
if(IsFormula())
return FALSE;//illogicality return
BOOL bRet=TRUE;
EmptyStack(Operator);
EmptyStack(Oprand);
CString string=m_formula;
bRet=bRet&&GetOperatorStack(Operator,string);
bRet=bRet&&GetOperandStack(Oprand,string);
return bRet;
}
BOOL CStringResolution::Initialize()
{
BOOL bRet=FALSE;
OperatorStack Op; OperandStack Od;
bRet=GetStack(Op,Od);
if(!bRet)
{
EmptyStack(Op);
EmptyStack(Od);
return FALSE;
}
m_oprandNum=Od.size(),m_operatorNum=Op.size();
if(m_operatorNum)
m_operator=new COperator[m_operatorNum];
if(m_oprandNum)
m_oprand=new COperand[m_oprandNum];
int i;
for(i=0;i<m_operatorNum;i++)
{
COperator*op=Op.top();
m_operator[m_operatorNum-i-1]=*op;
Op.pop();
delete op;
}
for(i=0;i<m_oprandNum;i++)
{
COperand*od=Od.top();
m_oprand[m_oprandNum-i-1]=*od;
Od.pop();
delete od;
}
m_oprandA=new COperand[m_oprandNum];
BOOL IsIn=FALSE;
for(i=0;i<m_oprandNum;i++)
{
for(int j=0;j<m_oprandANum;j++)
{
if(m_oprand[i]==m_oprandA[j])
{
IsIn=TRUE;
break;
}
}
if(!IsIn&&!m_oprand[i].m_IsConst)
{
m_oprandA[m_oprandANum]=m_oprand[i];
m_oprandANum++;
}
IsIn=FALSE;
}
return TRUE;
}
double CStringResolution::Computer(OperatorStack &Operator, OperandStack &Oprand)
{
double value =0.0;
if(Operator.empty())
{
if(Oprand.size()==1)
{
COperand* od=Oprand.top();
value=atof(od->m_name);
delete od;
return value;
}
else
{
while(!Oprand.empty())
{
COperand*od=Oprand.top();
Oprand.pop();
delete od;
}
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(12,TRUE,"Oprand is less or more!");
#endif
return BIGNUMBER;
}
}
OperatorStack tmpOO;
OperandStack tmpOD;
COperator* op=0,*op1=0;
COperand *oprand=0,*oprand1=0;
op=Operator.top();
Operator.pop();
if(!Operator.empty())
op1=Operator.top();
while(op1&&(op1->m_level>op->m_level))
{
tmpOO.push(op);
if(op->m_type==BINARY)
{
if(!Oprand.empty())
{
oprand=Oprand.top();
Oprand.pop();
tmpOD.push(oprand);
}
}
op=op1;
Operator.pop();
if(!Operator.empty())
op1=Operator.top();
else
op1=0;
}
if(op->m_type==UNARY)
{
if(Oprand.empty())
{
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(12,TRUE,"Oprand is less!");
#endif
return BIGNUMBER;
}
oprand=Oprand.top();
double x=computing(op,oprand);
oprand->m_name.Format("%g",x);
}
else
{
if(Oprand.empty())
{
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(12,TRUE,"Oprand less!");
#endif
return BIGNUMBER;
}
oprand1=Oprand.top();
Oprand.pop();
if(Oprand.empty())
{
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(12,TRUE,"Oprand less!");
#endif
return BIGNUMBER;
}
oprand=Oprand.top();
double x=computing(op,oprand1,oprand);
oprand->m_name.Format("%g",x);
delete oprand1;
}
delete op;
while(!tmpOO.empty())
{
op=tmpOO.top();
tmpOO.pop();
Operator.push(op);
}
while(!tmpOD.empty())
{
oprand=tmpOD.top();
tmpOD.pop();
Oprand.push(oprand);
}
return Computer(Operator,Oprand);
}
double CStringResolution::computer(double variantValue[], int num)
{
#ifdef _ERROR_INFO_H_
PROCESSION_ERROR
#endif
double value=0.0;
int i;
if(num<m_oprandANum)
{
#ifdef _ERROR_INFO_H_
_SAVE_ERROR_INFO(10,FALSE,"There are less digital number than variants");
#endif
return BIGNUMBER;
}
OperatorStack Operator;
OperandStack Oprand;
for(i=0;i<m_operatorNum;i++)
{
COperator*op=new COperator;
*op=m_operator[m_operatorNum-i-1];
Operator.push(op);
}
for(i=0;i<m_oprandNum;i++)
{
COperand*od=new COperand;
*od=m_oprand[m_oprandNum-i-1];
for(int j=0;j<m_oprandANum;j++)
{
if(*od==m_oprandA[j])
od->m_name.Format("%g",variantValue[j]);
}
Oprand.push(od);
}
value=Computer(Operator,Oprand);
return value;
}
CString CStringResolution::GetErrorInformation()
{
CString value;
#ifndef _ERROR_INFO_H_
value="There is no error information.";
#else
GET_ERROR_INFORMATION(value)
#endif
return value;
}
BOOL CStringResolution::EmptyStack(OperatorStack Op)
{
while(!Op.empty())
{
COperator*op=Op.top();
Op.pop();
delete op;
}
return TRUE;
}
BOOL CStringResolution::EmptyStack(OperandStack Od)
{
while(!Od.empty())
{
COperand*od=Od.top();
Od.pop();
delete od;
}
return TRUE;
}
BOOL CStringResolution::GetOperatorStack(OperatorStack &Operator, CString &string)
{
BOOL bRet=TRUE;
int num=string.GetLength();
int i=0;
int level=0;
while(i<num)
{
if(string[i]=='(')
{
level+=LEVELS;
string.SetAt(i,'#');
i++;
}
else if(string[i]==')')
{
level-=LEVELS;
string.SetAt(i,'@');
i++;
}
else if(string[i]=='+'||string[i]=='-')
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -