//////////////////////////////////////////////////////////////
/////////////////arithmetic expression calculate///////////////
///////////////Copy is forbided Copyright reserve///////////
///////////////////////////////////////////////////////////////
#include
#include
#define NULL 0
#define NL printf("\n");
#define PI 3.14159265358979323846264338327
class CALCULATE
{
public:
//默认初始化构造函数
CALCULATE();
//字符是否为1---9或小数点
int IsFigure(char *figure);
//是否为运算符
int IsSign(char *sign);
//运算符优先级判断函数
int OperaterPriority(char *priority);
//二目运算操作a,b,"act"
long double CalculateAB(long double a,long double b,char *act);
//计算字符串结果 signal 为1时单目运算符标记,否则为0
long double CalculateExpression(char *addr,int signal);
//字符串拷贝
char * StringCopy(char * aim,const char *data);
///在结尾追加字符串
char * Add(char *aim,const char *data);
////开始计算
void Calculate();
//表达式有错时标记 1
int ErrorMark;
//是否为有效字符单目运算符0x10~~0x16二目+-*/%^数字0~9
int IsEffect(char *data);
//可以用不可显示的字符替换
int Replace(char *aim, char *data,int replace);
public:
//储存表达式
char Expression[150];
//存储表达式副本
char TempExpression[150];
//存储错误信息
char ErrorInformation[100];
//以字符串形式存储结果
char CharCalculateResult[50];
//双精度结果15个有效位
long double DoubleCalculateResult;
};
CALCULATE::CALCULATE()
{Expression[0]=0;
CharCalculateResult[0]=0;
TempExpression[0]=0;
}
char * CALCULATE::Add(char *aim,const char *data)
{ char *first=aim;
while(*aim++);aim--;
while(*aim++=*data++);;
return first;
}
int CALCULATE::Replace(char *aim, char *data,int replace)
{ int ReplaceOffset,AimOffset;
int StartOffset,DataOffset=0;
int NUM=0;
char *Data=data;
for(AimOffset=0;*(aim+AimOffset)!=0;AimOffset++)
{StartOffset=AimOffset;
while(*(aim+AimOffset)==*(Data+DataOffset)
&&*(aim+AimOffset))
{ AimOffset++;
DataOffset++;
}//找*data
if(*(Data+DataOffset)==0)
//如果该条件成立则找到了*data
{ NUM++;//NUM为找到*data的个数
*(aim+StartOffset)=replace;
ReplaceOffset=StartOffset+1;
//设置替换的位置
for(;*(aim+ReplaceOffset)!=0;ReplaceOffset++)
*(aim+ReplaceOffset)=*(aim+ReplaceOffset+DataOffset-1);//
}
AimOffset=StartOffset;
DataOffset=0;
}
if(NUM)return 1;
else return 0;
}
char * CALCULATE::StringCopy(char * aim,const char *data)
{ char * first=aim;
while ((*aim++=*data++)&&(*data));
return first;
}
void CALCULATE::Calculate()
{ StringCopy(TempExpression,Expression);
DoubleCalculateResult=CalculateExpression(Expression,0);
}
int CALCULATE::IsEffect(char *data)
{//表达式非法字符的判断
if( (0x10<=*data&&*data<=0x1A)
||(0x2d<=*data&&*data<=0x39)
||(0x28<=*data&&*data<=0x2b)
||*data==0x25||*data==0x3d
||*data==0x5e
)return 1;
else return 0;
}
int CALCULATE::IsFigure(char *figure)
{ if('0'<=*figure&&*figure<='9'||*figure=='.')return 1;
else return 0;
}
int CALCULATE::IsSign(char *sign)
{//运算符号判断
switch(*sign)
{
case '+':return '+';
case '-':return '-';
case '*':return '*';
case '/':return '/';
case '^':return '^';
case '%':return '%';
case ')':return ')';
case '=':return '=';
default :return 0;
}
}
int CALCULATE::OperaterPriority(char *priority)
{ switch(*priority)//运算符号优先级判断
{ case '+':return 4;break;
case '-':return 4;break;
case '*':return 6;break;
case '/':return 6;break;
case '^':return 9;break;
case '%':return 6;break;
case ')':return 2;break;
case '=':return 2;break;
//括号和等号具有相同优先级表示一个计算过程的结束
default :return 0;break;
}
}
long double CALCULATE::CalculateAB(long double a,
long double b,char *act)
{
switch(*act)//二目表达式计算
{ case '+':return a+b;break;
case '-':return a-b;break;
case '*':return a*b;break;
case '/':return a/b;break;
case '%':return (long int)a%(long int)b;break;
case '^':return pow(a,b);break;
default:return 5201314;
}
}
long double CALCULATE::CalculateExpression(char *addr,int signal)
///*addr表达式字符串地址 signal为单目计算标志0或非0
{
char temp[60];
int BracketNumber=0,BracketNumber1=0,kk=0;
int oo=0;//错误定位矫正
char s;
ErrorInformation[0]='\0';//
ErrorMark=0;//
int arrayOffset=0;//字符串偏移量
struct calculate_Space
{
long double value[50];//建立数字堆栈
char sign[50];//建立运算符号堆栈
int valueOffset;//值偏移量
int signOffset;//符号偏移量
} *pp,ppp;
pp=&ppp;
pp->value[0]=0;
pp->signOffset=0;
pp->sign[0]='\0';
Replace(Expression,"-", '-');
Replace(Expression,"+", '+');
Replace(Expression,"×", '*');
Replace(Expression,"÷", '/');
Replace(Expression,"√", 0x16);
///////////使表达式能够处理负数///////////////////////
if(*addr=='-'||*addr=='+')
{
pp->valueOffset=1;pp->value[0]=0;
}//使表达式
else if(*addr=='*'||*addr=='/'||*addr=='^')
{
ErrorMark=1;//
sprintf(temp," !! 出错位置 %2d: 运算符" /////
" \" %c \" 多余\r\n", /////
addr-Expression+1,*addr);/////
Add(ErrorInformation,temp);
}
else
{
pp->valueOffset=0;
pp->value[0]=0;
}//能够处理负数
/////////////////////////////////////////////////////////
if(*addr==0)
{
ErrorMark=1;
Add(ErrorInformation,//判断表达式是否存在
" !! 出错.... : 您还没有输入表达式.\r\n");
}
///////////////////////////////////////////////////////////
for(kk=0;*(Expression+kk)!='\0';kk++);
if(*(Expression+kk-1)!='=') //保证表达式最后有等号
{
*(Expression+kk)='=';
*(Expression+kk+1)='\0';
}
//////////////////////////////////////////////////////////////
Replace(Expression,"arcsin", 0x17);
Replace(Expression,"arccos", 0x18);
Replace(Expression,"arcctg", 0x1A);
Replace(Expression,"arctg", 0x19);
//////////////////////////////////////////////
Replace(Expression,"sqrt",0x16);
Replace(Expression,"sin", 0x10);
Replace(Expression,"log", 0x15);
Replace(Expression,"cos", 0x11);//设置单目
Replace(Expression,"ctg", 0x13);//运算符
Replace(Expression,"tg", 0x12);//
Replace(Expression,"ln", 0x14);
///////////////////////////////////////////////////////////////
for(kk=0;IsEffect(Expression+kk);kk++)//是否有非法字符
{
switch(*(Expression+kk))
{case 0x10:
case 0x11:
case 0x13:
case 0x15:oo+=2;break;
case 0x12:
case 0x14:oo++; break;
case 0x16:oo+=3;break;
case 0x17://OO错误位置的偏移量
case 0x18:
case 0x1A:oo+=5;break;
case 0x19:oo+=4;break;
}
if(*(Expression+kk)>=0x10&&*(Expression+kk)<=0x1A
&&IsSign(Expression+kk+1))
{
ErrorMark=1;
sprintf(temp," !! 出错位置 %2d: 应该为数字 0 --- 9\r\n",
kk+oo+2);kk++;
Add(ErrorInformation,temp); break;
}
}//进行替换后原表达式发生改变,以上是为了精确定位错误
///////////////////////////////////////////////////////
if(*(Expression+kk)!='\0')//判断是否正常结束
{
ErrorMark=1;//如果以\0结束则没有非法字符
if(*(Expression+kk)!=0x20&&*(Expression+kk)!='=')
{
sprintf(temp," !! 出错位置 %2d: "
"字符 \" %c \" 非法 !!!\r\n",
kk+oo+1,*(Expression+kk));//oo对错误位矫正
Add(ErrorInformation,temp);
}
else if(*(Expression+kk)==' ')
//如果是空格显示相应的错误信息
{
sprintf(temp," !! 出错位置 %2d: "
"表达式不能有空格 !!!\r\n",
kk+oo+1);Add(ErrorInformation,temp);
}//oo对错误位矫正
}
//////////////////////////////////////////////////////
int EqualNum=0;//判断等号是否多余
for(kk=0;*(Expression+kk)!='\0';kk++)
if(*(Expression+kk)=='=')EqualNum++;
if(EqualNum>1)
{
ErrorMark=1;//printf("%d\n",EqualNum);
Add(ErrorInformation," !! 出错位置 未知: 表达式多处出现"
"\" = \"....\r\n");
}