📄 expressioncompli.cpp
字号:
/* Class CExpression CPP
/ By Great_csk 2004
/
/
*/
#include "ExpressionCompli.h"
#include ".\expressioncompli.h"
#include <cstdio>
#define SAFE_DELETE(p) ((p==0)?0:delete p)
CExpression::CExpression() : nScanPos(0)
{
t_expression =new char[MAX_EXP];
n_last_error=ERROR_NULL;
num_table="0123456789.";
operator_table="+-*/()# ^";
}
CExpression::~CExpression(){
ClearStack();
delete[] t_expression;
}
hResult CExpression::Compile(){
//
if (n_last_error!=ERROR_NULL) return n_last_error;
int prev_operator,cur_operator;
long tresult;
EXP_ITEM *tmpItem;
prev_operator=' ';
ClearStack();
pexpItem=new EXP_ITEM;
while(tresult=GetNextStrItem(pexpItem)){
if (pexpItem->item_type==ITEM_TYPE_OPERATOR){
cur_operator=pexpItem->itemdata.operator_data;
if (tresult=operatorToStack(prev_operator,cur_operator)!=ERROR_NULL){
SAFE_DELETE( pexpItem);
return tresult;
}
tmpItem=(EXP_ITEM *)stkItems.getTop();
if (tmpItem==0){
SAFE_DELETE( pexpItem);
n_last_error=ERROR_STACK_ERROR;
return ERROR_STACK_ERROR;
}
prev_operator=tmpItem->itemdata.operator_data;
}else
{
printf("%g,",pexpItem->itemdata.num_data);
stkExp.AddNode((void *)pexpItem);
}
pexpItem=new EXP_ITEM;
}
ClearStack(STACK_ITEM);
if (n_last_error==ERROR_COMPLINE) {
return ERROR_COMPLINE;
}
return ERROR_NULL;
}
hResult CExpression::Solve(double &result){
EXP_ITEM *num1,*num2;
EXP_ITEM *tmpItem;
double tmpData;
num2=num1=NULL;
if (n_last_error!=ERROR_NULL) return n_last_error;
ClearStack(STACK_ITEM);
stkExp.GotoFirst();
do{
pexpItem=(EXP_ITEM *)stkExp.ReadNode();
if (pexpItem==0){
ClearStack(STACK_ITEM);
return n_last_error=ERROR_EXP_END;
}
switch(pexpItem->item_type){
case ITEM_TYPE_OPERATOR:
//Is Operator
num2=(EXP_ITEM *)stkItems.pop();
num1=(EXP_ITEM *)stkItems.pop();
if (num1==0 || num2==0){
SAFE_DELETE(num1);
SAFE_DELETE(num2);
ClearStack(STACK_ITEM);
n_last_error=ERROR_STACK_ERROR;
return n_last_error;
}
if (num1->item_type!=ITEM_TYPE_NUM || num2->item_type!=ITEM_TYPE_NUM){
SAFE_DELETE(num1);
SAFE_DELETE(num2);
n_last_error=ERROR_BAD_USEAGE;
ClearStack(STACK_ITEM);
return n_last_error;
}
tmpData=CalculateValueByOperator(num1->itemdata.num_data,num2->itemdata.num_data,pexpItem->itemdata.operator_data);
if (n_last_error!=ERROR_NULL) {
SAFE_DELETE(num1);
SAFE_DELETE(num2);
ClearStack(STACK_ITEM);
return n_last_error;
}
num1->itemdata.num_data=tmpData;
stkItems.push((pData)num1);
delete num2;
break;
case ITEM_TYPE_NUM:
//Is Num
tmpItem=new EXP_ITEM;
*tmpItem=*pexpItem;
stkItems.push((pData)tmpItem);
break;
}
}while(stkExp.GotoNext());
pexpItem=(EXP_ITEM *)stkItems.pop();
if (pexpItem){
if (pexpItem->item_type==ITEM_TYPE_NUM){
result=pexpItem->itemdata.num_data;
n_last_error=ERROR_NULL;
}else
{
n_last_error=ERROR_BAD_USEAGE;
}
}else
{
n_last_error=ERROR_STACK_ERROR;
}
SAFE_DELETE( pexpItem );
ClearStack(STACK_ITEM);
return n_last_error;
}
hResult CExpression::SetExpression(pExpression exp){
int i,j;
char holder;
n_last_error=ERROR_NULL;
t_expression[0]='#';
ClearStack();
j=1;i=0;
while(exp[i]){
holder=exp[i];
if (holder=='(' && GetDataType(t_expression[j-1])==ITEM_TYPE_NUM){
t_expression[j]='*';
j++;
}
t_expression[j]=holder;
i++;
j++;
}
t_expression[j]='#';
t_expression[j+1]='\0';
nScanPos=0;
return 0;
}
long CExpression::GetNextStrItem(EXP_ITEM * pItem)
{
char CurrentType,PrevType;
char CurrentChar;
int OrgPos;
PrevType=CurrentType=ITEM_TYPE_NULL;
CurrentChar=*(t_expression+nScanPos);
OrgPos=nScanPos;
while(CurrentChar){
CurrentType=GetDataType(CurrentChar);
nScanPos++;
if (CurrentType==ITEM_TYPE_OPERATOR){
if (CurrentChar=='-' || CurrentChar=='+'){ //-a?
if ( GetDataType(*(t_expression+nScanPos)) == ITEM_TYPE_OPERATOR ){
pItem->item_type=ITEM_TYPE_OPERATOR;
pItem->itemdata.operator_data=CurrentChar;
return true;
}else
{
pItem->item_type=ITEM_TYPE_OPERATOR;
pItem->itemdata.operator_data=CurrentChar;
return true;
}
}
else{
pItem->item_type=ITEM_TYPE_OPERATOR;
pItem->itemdata.operator_data=CurrentChar;
return true;
}
}
if (CurrentType==ITEM_TYPE_NUM && GetDataType(*(t_expression+nScanPos))==ITEM_TYPE_OPERATOR && *(t_expression+nScanPos-2)!=')'){
pItem->item_type=ITEM_TYPE_NUM;
if (StrToFloat(t_expression,OrgPos,nScanPos-1,&pItem->itemdata.num_data)!=COMPLINE_SUCCEED)
{
n_last_error=ERROR_COMPLINE;
return false;
}
return true;
}
if (CurrentType==ITEM_TYPE_NULL){
n_last_error=ERROR_COMPLINE;
return false;
}
CurrentChar=*(t_expression+nScanPos);
PrevType=CurrentType;
}
n_last_error=ERROR_EXP_END;
return false;
}
char CExpression::GetDataType(char t_char)
{
if (IsInTheTable(num_table,t_char)) return ITEM_TYPE_NUM;
if (IsInTheTable(operator_table,t_char)) return ITEM_TYPE_OPERATOR;
return ITEM_TYPE_NULL;
}
bool CExpression::IsInTheTable(char * pTable,char QueryChar)
{
int scanpoint=0;
char scanchar;
scanchar=*(pTable+scanpoint);
while(scanchar){
if (scanchar==QueryChar) return true;
scanpoint++;
scanchar=*(pTable+scanpoint);
}
return false;
}
int CExpression::StrToFloat(pExpression pExp, int start, int end, double* ans)
{
int scanPos;
bool IsNeg,//<0?
Isfloat;
char CurrentChar;
int floatpoint;
scanPos=start;
IsNeg=false;
Isfloat=false;
*ans=0;
if (pExp[start]=='-' || pExp[start]=='+'){
scanPos++;
IsNeg=(pExp[start]=='-');
}
for (;scanPos<=end;scanPos++){
CurrentChar=pExp[scanPos];
if (CurrentChar=='.'){
if (Isfloat) return COMPLINE_BAD_TYPE; //more than one '.'
floatpoint=scanPos;
Isfloat=true; //is float num
}
else{
if (CurrentChar>='0' && CurrentChar<='9'){
*ans*=10;
*ans+=CurrentChar-'0';
}else{
//return COMPLINE_BAD_TYPE;
}
}
}
if (Isfloat==true){
for (int i=0;i<scanPos-floatpoint-1;i++){
(*ans)/=10;
}
}
if (IsNeg) *ans=-(*ans);
return COMPLINE_SUCCEED;
}
bool CExpression::ClearStack(int nType)
{
if (nType==STACK_ALL || nType==STACK_EXP){
stkExp.GotoEnd();
while(pexpItem=(EXP_ITEM *)stkExp.ReadNode()){
SAFE_DELETE( pexpItem);
stkExp.DeleteNode();
}
}
if (nType==STACK_ALL || nType==STACK_ITEM){
while(pexpItem=(EXP_ITEM *)stkItems.pop()){
SAFE_DELETE( pexpItem);
}
}
return false;
}
int CExpression::OperatorComp(char operator1, char operator2)
{
char op_ID_1,op_ID_2;
char i;
/*
+ - * / ( ) # 0 ^
-------------------------------
+ > > < < < > > N <
- > > < < < > > N <
* > > > > < > > N <
/ > > > > < > > N <
( < < < < < = N N <
) > > > > N > > N >
# < < < < < = < > <
0 N N N N N N < N N
^ > > > > < > > N >
*/
int operator_level[9][9]={
1, 1,-1,-1,-1, 1, 1, 'N',-1,
1, 1,-1,-1,-1, 1, 1, 'N',-1,
1, 1, 1, 1,-1, 1, 1, 'N',-1,
1, 1, 1, 1,-1, 1, 1, 'N',-1,
-1,-1,-1,-1,-1, 0,'N','N',-1,
1, 1, 1, 1,'N',1, 1, 'N', 1,
-1,-1,-1,-1,-1, 'N', 0, 1 ,-1,
'N','N','N','N','N','N', -1,'N','N',
1, 1, 1, 1,-1, 1, 1,'N',1
};
for (i=0;i<9;i++){
if (operator_table[i]==operator1) op_ID_1=i;
if (operator_table[i]==operator2) op_ID_2=i;
}
return operator_level[op_ID_1][op_ID_2];
}
int CExpression::operatorToStack(char operator1, char operator2)
{
EXP_ITEM *tmpItem;
switch(OperatorComp(operator1,operator2)){
case 0: // ==
if (operator1=='(' && operator2==')'){
tmpItem= (EXP_ITEM *)stkItems.pop();
if (tmpItem==0){
n_last_error=ERROR_STACK_ERROR;
return ERROR_STACK_ERROR;
}
delete tmpItem;
}
break;
case 1: // >
tmpItem=(EXP_ITEM *)stkItems.pop();
if (tmpItem==0){
n_last_error=ERROR_STACK_ERROR;
return ERROR_STACK_ERROR;
}
printf("<%c>",tmpItem->itemdata.operator_data);
stkExp.AddNode((void *)tmpItem);
tmpItem=(EXP_ITEM *)stkItems.getTop();
if (tmpItem==0){
n_last_error=ERROR_STACK_ERROR;
return ERROR_STACK_ERROR;
}
return operatorToStack(tmpItem->itemdata.operator_data,operator2);
break;
case -1: // <
if (stkItems.push((pData)pexpItem)==0){
n_last_error=ERROR_STACK_OVERFLOW;
return ERROR_STACK_OVERFLOW;
}
break;
case 'N':// N/A
n_last_error=ERROR_BAD_USEAGE;
return ERROR_BAD_USEAGE;
break;
}
return ERROR_NULL;
}
double CExpression::CalculateValueByOperator(double num1, double num2, char Operator)
{
n_last_error=ERROR_NULL;
switch(Operator){
case '+':
return num1+num2;
break;
case '-':
return num1-num2;
break;
case '*':
return num1*num2;
break;
case '/':
if (num2){
return num1/num2;
}else
{
n_last_error=ERROR_DIVIDED_BY_ZERO;
}
break;
case '^':
break;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -