// MathString.cpp: implementation of the CMathString class.
//
////////////////////////////////////////////////////////////////////
// MathString.cpp: implementation of the CMathString class.
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// 功能:
// 求字符串中表达式的值,
//
// 特点:
// 1.支持字符串中含有各种常用函数,如"7.5+sin(6*ln(8))/exp(5)"
// 2.具有很好的纠错能力,能检查出表达式中括号是否配对、库函数是
// 否正确
// 3.运算过程中能检查出各种异常,如除数为0、开方函数sqrt(x)中x<0
// 反余弦函数acos(x)中的x<-1或x>1等
// 4.为支持积分和积分的混合运算
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// 使用方法:
// 1. 定义一个CMathString 的对象,用要求的算术表达式将其初始化
// 如: char *s1="7.5+sin(6)/exp(5)";
// char *s2="4*pow(x,2)+2*x+4";
// CMathString mathstr1(s1);
// CMathString mathstr2(s2);
// 2.调用checkString检查表达式是否合法
// 3.调用stringToBolan()将算术表达式转换为波兰表达式
// 4.调用compvalue()对波兰表达式进行计算,若返回值为0,则调
// 用getvalue()取得计算结果,否则可根据返回值判断出错地方
// 5.调用compvalue1()积分表达式进行计算,若返回计算值
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//
// 支持的函数的编号及功能
//
// 编号 函数 功能 调用的math.h库函数 备注
//
// 1 abs(x) 取绝对值|x| fabs(x)
// 2 acos(x) 反余弦函数 acos(x) -1<=x<=1
// 3 asin(x) 反正弦函数 asin(x) -1<=x<=1
// 4 atan(x) 反正切函数 atan(x)
// 5 acot(x) 反余切函数 PI/2-atan(x)
// 6 cos(x) 余弦函数 cos(x)
// 7 csh(x) 双曲余弦函数 cosh(x)
// 8 cot(x) 余切函数 1/tan(x) tan(x)!=0
// 9 exp(x) e的x次方 exp(x)
// 10 floor(x) ⊥x⊥ floor(x) 求不大于x的最大整数
// 11 mod(x,y) x%y mod(x,y) y!=0
// 12 ln(x) 取自然对数 log(x) x>0
// 13 log(x) 取10的对数 log10(x) x>0
// 14 pow(x,y) x的y次方 pow(x,y)
// 15 sin(x) 正弦函数 sin(x)
// 16 snh(x) 双曲正弦函数 sinh(x)
// 17 sqrt(x) 对x开方 sqrt(x) x>=0
// 18 tan(x) 正切函数 tan(x)
// 19 tnh(x) 双曲正切函数 tanh(x)
// 20 <f(x),LowerLimit,UpperLimit> 自定义积分函数 f(x)为用户自定义函数
//
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MathString.h"
#include "math.h"
#define PI 3.1415926
#define E 2.718281828
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
void CMathString::Initial(char *s)
{ //初始化函数,将算术表达式s赋给成员变量String
strcpy(string,s);
}
int CMathString::checkString()
{ //检查输入的表达式是否正确,包括括号是否配对、库函数是否正确,
//不包括小数点是否正确,若正确,将表达式中的大、中括号改成小括号
//并在表达式尾加‘#’标识
//若算术表达式正确,返回值为1;否则返回0;
//因积分表达式中有x,所以表达式中的x的flag标志为3
char st[MAX/2];//存放括号的栈
int top=0,
j, //栈顶
i;
for(i=0;i<MAX/2;i++)st[i]=0;//对栈进行初始化
for(j=i=0;string[i]!='\0';i++)//删除表达式串中的所有空格,使空格不影响表达式,增强容错能力
if(string[i]!=' ')
string[j++]=string[i];
string[j]='\0';
for(i=0;string[i]!='\0';i++)//删除表达式串中的连续的+,使+不影响表达式,增强容错能力
while(string[i]=='+'&&string[i+1]=='+')
{
j=i;
while(string[j]!='\0')
{string[j]=string[j+1];j++;}
}
for(i=0;string[i]!='\0';i++)//删除表达式串中的连续的-,使-不影响表达式,增强容错能力
while(string[i]=='-'&&string[i+1]=='-')
{
j=i;
while(string[j]!='\0')
{string[j]=string[j+1];j++;}
}
for(i=0;string[i]!='\0';i++)//删除表达式串中的连续的*,使*不影响表达式,增强容错能力
while(string[i]=='*'&&string[i+1]=='*')
{
j=i;
while(string[j]!='\0')
{string[j]=string[j+1];j++;}
}
for(i=0;string[i]!='\0';i++)//删除表达式串中的连续的/,使/不影响表达式,增强容错能力
while(string[i]=='/'&&string[i+1]=='/')
{
j=i;
while(string[j]!='\0')
{string[j]=string[j+1];j++;}
}
for(i=0;string[i]!='\0';i++)//这是一个非常大的for循环
{
//如果是左括号,则入栈
if(string[i]=='(' || string[i]=='[' || string[i]=='{'|| string[i]=='<')
{ //如果是左括号,则入栈
top++;
st[top]=string[i];
continue;
}
//小括号
if(string[i]==')') //小括号
{
if(st[top]=='(') //配对
{
st[top]=0; //出栈!!!!!!!!!!!!!!!!!!!!!
top--; //出栈
continue;
}
else return 0; //不配对,返回0
}
//中括号
if(string[i]==']')
{
if(st[top]=='[') //配对
{
st[top]=0; //出栈!!!!!!!!!!!!!!!!!!!!!
top--; //出栈
continue;
}
else return 0; //不配对,返回0
}
//大括号
if(string[i]=='}')
{
if(st[top]=='{') //配对
{
st[top]=0; //出栈!!!!!!!!!!!!!!!!!!!!!
top--; //出栈
continue;
}
else return 0; //不配对,返回0
}
//角括号
if(string[i]=='>') //角括号
{
if(st[top]=='<') //配对
{
st[top]=0; //出栈!!!!!!!!!!!!!!!!!!!!!
top--; //出栈
continue;
}
else return 0; //不配对,返回0
}
//运算符
if(string[i]=='+' || string[i]=='-' || string[i]=='*' || string[i]=='/')
{ //如果有重复运算符则错误
if(string[i+1]=='+' || string[i+1]=='-' || string[i+1]=='*' ||string[i+1]=='/')
return 0; //错误,返回0
else
continue; //无连续运算符情况
}
//数字、小数点、逗号
if(('0'<=string[i] && string[i]<='9') || string[i]=='.'||string[i]==',')
continue;
//未知数x
if(string[i]=='x')
continue;
//是以a开头的函数
if(string[i]=='a')
{
if(seekStr(string,i,"abs")||seekStr(string,i,"acos")||
seekStr(string,i,"asin")||seekStr(string,i,"atan")||
seekStr(string,i,"acot"))//是以a开头的库函数
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函数后是括号
st[++top]=string[i]; // 括号入栈
continue;
}
else //如果函数后不是括号,返回0
return 0;
}
else //不是以a开头的库函数,返回0
return 0;
}
//是以c开头的函数
if(string[i]=='c')
{
if(seekStr(string,i,"cos")||seekStr(string,i,"csh")||
seekStr(string,i,"cot"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函数后是括号
st[++top]=string[i]; // 括号入栈
continue;
}
else //如果函数后不是括号,返回0
return 0;
}
else //不是以c开头的库函数,返回0
return 0;
}
//是以e开头的函数
if(string[i]=='e')
{
if(seekStr(string,i,"exp"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函数后是括号
st[++top]=string[i]; // 括号入栈
continue;
}
else //如果函数后不是括号,返回0
return 0;
}
else //不是以e开头的库函数,返回0
return 0;
}
//是以f开头的函数
if(string[i]=='f')
{
if(seekStr(string,i,"floor"))
{
if(string[i]=='('||string[i]=='['||string[i]=='{')
{ //如果函数后是括号
st[++top]=string[i]; // 括号入栈
continue;
}
else //如果函数后不是括号,返回0
return 0;
}
else //不是以f开头的库函数,返回0
return 0;
}
//是以m开头的函数
if(string[i]=='m')
{
if(seekStr(string,i,"mod"))
{
if(string[i]=='('