www.gusucode.com > 一个求积分的VC++类及Demo源代码-源码程序 > 一个求积分的VC++类及Demo源代码-源码程序/code/MathString.cpp

    // MathString.cpp: implementation of the CMathString class.
// Download by http://www.NewXing.com
////////////////////////////////////////////////////////////////////
// MathString.cpp: implementation of the CMathString class.
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////                    
//
//                   求算术表达式值的类
//
//              湖南城市学院  信息与计算科学系  
//                        黄江峰
//                 jiangfenghuang@msn.com
//                 jiangfenghuang@163.net
//                       2003.4.5           
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
// 功能:
//      求在字符串中的算术表达式的值,
//   
// 特点:
//      1.支持字符串中含有各种常用函数,如"7.5+sin(6*ln(8))/exp(5)"
//      2.具有很好的纠错能力,能检查出表达式中括号是否配对、库函数是
//        否正确
//      3.运算过程中能检查出各种异常,如除数为0、开方函数sqrt(x)中x<0
//        反余弦函数acos(x)中的x<-1或x>1等
//      4.为支持积分、求方程,算术表达式中可含有x,计算时将用类中的成
//        员变量xx代替 
//////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////// 
//
// 使用方法:
//      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);
//        或调用Initial(char *s)、Initial(char *s,double x)将其初始化
//      2.调用checkString方法检查表达式是否合法
//      3.如果是求积分或j解方程,调用setX(double x)设置表达式中x的值
//      4.调用stringToBolan()将算术表达式转换为波兰表达式
//      5.调用compvalue()对波兰表达式进行计算,若返回值为0,则调
//        用getvalue()取得计算结果,否则可根据返回值判断出错地方
//
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//
//                支持的函数的编号及功能
//
// 编号     函数         功能         调用的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      cosh(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      sinh(x)     双曲正弦函数   sinh(x)
//  17      sqrt(x)     对x开方        sqrt(x)            x>=0
//  18      tan(x)      正切函数       tan(x)
//  19      tanh(x)     双曲正切函数   tanh(x)
//
/////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MathString.h"
#include "math.h"
#include "string.h"

#define PI  3.1415926

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMathString::CMathString()
{

}

CMathString::~CMathString()
{

}


CMathString::CMathString(char *str)  //构造函数,将算术表达式str赋给String
{
	strcpy(string,str);            
}

CMathString::CMathString(char *str,double x)
{    //表达式中带未知数的构造函数
	 //算术表达式*str赋给string,未知数x赋给xx
	 //用于积分表达式
	strcpy(string,str);
	xx=x;
}

void CMathString::setX(double x)      //设置成员变量xx的值
{
	xx=x;
}

int CMathString::seekStr(char *str,int &i, char *s)
{   //检查字符窜str的第i个位置开始的后面字符是否与字符窜s相匹配
	//是的话将i=i+len(s),并返回1,否则返回0
	int j=0;
	for(j=0;j<strlen(s);j++)
		if(str[i+j]!=s[j])
			break;
	if(j==strlen(s))
	{
		i=i+strlen(s);
		return 1;
	}
	else return 0;
}

void CMathString::Initial(char *s)  //初始化函数,将算术表达式s赋给String
{
	strcpy(string,s); 

}

void CMathString::Initial(char *str, double x)
{
	//表达式中带未知数的初始化函数
	 //算术表达式*str赋给string,未知数x赋给xx
	 //用于积分表达式
	strcpy(string,str);
	xx=x;

}


int CMathString::checkString()
{ //检查输入的表达式是否正确,包括括号是否配对、库函数是否正确,
  //不包括小数点是否正确,若正确,将表达式中的大、中括号该成小括号
  //并在表达式尾加‘#’标识
  //若正确,返回值为1;否则返回0;
  //因积分表达式中有x,所以表达式中的x作为字符处理
	char st[MAX/2];        //存放括号的栈
	int top=0,     //栈顶
		i;
	for(i=0;string[i]!='\0';i++)
	{
		//如果是左括号,则入栈
		if(string[i]=='(' || string[i]=='[' || string[i]=='{')
		{  //如果是左括号,则入栈
			top++;
			st[top]=string[i];
			continue;
		}
        
		//小括号
		if(string[i]==')')   //小括号
		{  
			if(st[top]=='(')   //配对
			{
				top--;         //出栈
				continue;
			}
			else return 0;    //不配对,返回0
		}
        //中括号
		if(string[i]==']')    
		{  
			if(st[top]=='[')   //配对
			{
				top--;         //出栈
				continue;
			}
			else return 0;    //不配对,返回0
		}
		//大括号
		if(string[i]=='}')    
		{  
			if(st[top]=='{')   //配对
			{
				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,"cosh")||
				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]=='('||string[i]=='['||string[i]=='{')
				{   //如果函数后是括号
					st[++top]=string[i];  // 括号入栈  
					continue;
				}
				else //如果函数后不是括号,返回0
					return 0;
			}
			else    //不是以m开头的库函数,返回0
				return 0;
		}
		//是以l开头的函数
		if(string[i]=='l')
		{
			if(seekStr(string,i,"ln")||seekStr(string,i,"log"))
			{
				if(string[i]=='('||string[i]=='['||string[i]=='{')
				{   //如果函数后是括号
					st[++top]=string[i];  // 括号入栈  
					continue;
				}
				else //如果函数后不是括号,返回0
					return 0;
			}
			else    //不是以l开头的库函数,返回0
				return 0;
		}
		//是以p开头的函数
		if(string[i]=='p')
		{
			if(seekStr(string,i,"pow"))
			{
				if(string[i]=='('||string[i]=='['||string[i]=='{')
				{   //如果函数后是括号
					st[++top]=string[i];  // 括号入栈  
					continue;
				}
				else //如果函数后不是括号,返回0
					return 0;
			}
			else    //不是以p开头的库函数,返回0
				return 0;
		}
		//是以s开头的函数
		if(string[i]=='s')
		{
			if(seekStr(string,i,"sin")||seekStr(string,i,"sinh")||
				seekStr(string,i,"sqrt"))
			{
				if(string[i]=='('||string[i]=='['||string[i]=='{')
				{   //如果函数后是括号
					st[++top]=string[i];  // 括号入栈  
					continue;
				}
				else //如果函数后不是括号,返回0
					return 0;
			}
			else    //不是以s开头的库函数,返回0
				return 0;
		}
		//是以t开头的函数
		if(string[i]=='t')
		{
			if(seekStr(string,i,"tan")||seekStr(string,i,"tanh"))
			{
				if(string[i]=='('||string[i]=='['||string[i]=='{')
				{   //如果函数后是括号
					st[++top]=string[i];  // 括号入栈  
					continue;
				}
				else //如果函数后不是括号,返回0
					return 0;
			}
			else    //不是以t开头的库函数,返回0
				return 0;
		}
		
		else // 如果string[i]是其他字符,则返回0
			return 0;
	}//for(i=0;string[i]!='\0';i++)
	
	if(top!=0)       //括号不匹配,返回0
		return 0;
    
	//表达式正确
	//在表达式尾加‘#’标识
	string[i]='#';
	string[++i]='\0';

	//将表达式中的大、中括号该成小括号
	for(i=0;string[i]!='\0';i++)
	{
		if((string[i]=='[')||(string[i]=='{'))
			string[i]='(';
		else if((string[i]==']')||(string[i]=='}'))
			string[i]=')';
	}
	return 1;	
}

//将算术表达式string转化成波兰表达式,
//波兰表达式放在bolan[]中
//转换方法:
//1.判定string[i]为数值,直接存入bolan数组中
//2.判定string[i]为'(',将此'('压入栈,
//  若'('前为数字,则在'('前加一对'*'的处理
//3.判定string[i]为')',则将栈stact中左括号'('以后的运算符和函数依次
//  弹出,并入数组bolan中,然后将左括号'('弹出
//4.判定string[i]为'-','+',则将当前栈stack中左括号'('以后(如无'('则
//  将栈stack中所有)的运算符和函数依次弹出,存入数组bolan中,然后将
//  '-'或'+'压入栈stack中
//  如果'-'在第一个位置或其前是'(',即'-'是负号,将'~'(取负)压入stack中
//5.判定string[i]为'*'或'/',则将栈stact中顶端连续的'*'或'/'或函数依次
//  弹出,存入数组bolan中,然后将'*'或'/'压入栈stact中
//6.判定string[i]为函数,则将该函数入栈stact中
//  存入栈stact中变量func的是该函数的编号,详细编号见头文件
//  若该函数前为数字,则在该函数入栈stact前加一次对'*'的处理
//7.判定string[i]=',',将栈stact中'('后的运算符和函数全部弹出,压入数
//  组bolan中,
//8.判定string[i]='x',则用类中未知数变量xx代替,压入数组bolan中 
//9.转换结束时,若栈stact不为空,则将栈内所有运算符和函数弹出,存入
//  数组bolan中
//10.转换结束,在数组bolan尾加一opera='#'作为结束符
int CMathString::stringToBolan()
{
	Bolan stack[MAX];         //存放运算符和函数的栈
	int top=0,         //存放栈stact的下标
		i,           //string的下标
		j=0,           //bolan数组的下标
		t;
	char digitStr[20];     //存放要转化成数值的字符串
	
	for(i=0;string[i]!='#';i++)
	{
		//判定为数值,直接存入bolan数组中
		if(('0'<=string[i] && string[i]<='9')||string[i]=='.') //数值
		{
			t=0;
			digitStr[t]=string[i];   //数字存入要转化成数值的字符串
			while(('0'<=string[i+1] && string[i+1]<='9')
				||string[i+1]=='.')  
			{                       //将连续数字入要转化成数值的字符串
				digitStr[++t]=string[i+1];
				i++;
			}
			digitStr[++t]='\0';
        	 //将数字字符串转化成数值,并且入bolan数组
			bolan[j].flag=0;    //标识该节点为数值
			bolan[j].value=stringToDigital(digitStr);
			j++;
			continue;
		}

		//判定为'(',将此'('压入栈
		//若'('前为数字,则在'('前加一对'*'的处理
		if(string[i]=='(')
		{
			if(string[i-1]<='0' || '9'<=string[i-1])//'('前不为数字
			{
			top++;
			stack[top].flag=1;  //标识该节点为运算符
			stack[top].oper='(';
			continue;
			}
			else      //'('前为数字
			{         //加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';

				//将'('压入栈stact中
				top++;
				stack[top].flag=1;
				stack[top].oper='(';
				continue;
			}
		}

		//判定为')',则将栈stact中左括号'('以后的运算符和函数依次弹出
		//寸入数组bolan中,然后将左括号'('弹出
		if(string[i]==')')
		{
			while(stack[top].oper!='(')
			{
				bolan[j]=stack[top];
				j++;
				top--;
			}
			top--;  //将左括号'('弹出
			continue;
		}

		//判定为'-','+',则将当前栈stack中左括号'('以后(如无'('则将
		//栈stack中所有)的运算符和函数依次弹出,存入数组bolan中,
		//然后将'-'或'+'压入栈stack中
		//如果'-'在第一个位置或其前是'(',即'-'是负号,将'~'压入stack中
		if(string[i]=='+' || string[i]=='-')
		{
			if(string[i]=='-'&&(i==0 || string[i-1]=='(')) //'-'是负号
			{
				top++;
				stack[top].flag=1;
				stack[top].oper='~';
				continue;
			}
			else             //'-','+'是加减符号
			{
				while(stack[top].oper!='(' && top!=0)
				{
					bolan[j]=stack[top]; //当前栈stack中的运算符和
				                        //函数依次弹出存入数组bolan中
				    j++;
				    top--;
				}
				//将'-'或'+'压入栈stack中
				top++;
				stack[top].flag=1;
				stack[top].oper=string[i];
				continue;
			}
		}

		//判定string[i]为'*'或'/',则将栈stact中顶端连续的'*'或'/'或函
		//数依次弹出,存入数组bolan中,然后将'*'或'/'压入栈stact中
		if(string[i]=='*' || string[i]=='/')
		{
			while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
			{
				bolan[j]=stack[top];
				j++;
				top--;
			}
			//将'*'或'/'压入栈stact中
			top++;
			stack[top].flag=1;
			stack[top].oper=string[i];
			continue;
		}

		//判定string[i]为函数,则将该函数入栈stact中
		//存入栈stact中变量func的是该函数的编号,详细编号见头文件
		//若该函数前为数字,则在该函数入栈stact前加一次对'*'的处理
		if(string[i]=='a')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
		 
		    //为abs(x)函数
		    if(seekStr(string,i,"abs"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=1;
				i--;                    //因为在seekStr函数中
				continue;               //i=i+strlen("abs");
				                        //i已指向函数abs的下一个字符
				                        //而在for语句中有i++,所以此处
				                        //i要减1
			}
			//为acos(x)函数
			if(seekStr(string,i,"acos"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=2;
				i--;                     
				continue;  
			}
			//为asin(x)函数
			if(seekStr(string,i,"asin"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=3;
				i--;                     
				continue;  
			}
			//为atan(x)函数
			if(seekStr(string,i,"atan"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=4;
				i--;                     
				continue;  
			}
			//为acot(x)函数
			if(seekStr(string,i,"acot"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=5;
				i--;                     
				continue;  
			}
		}//if(string[i]=='a')
		//string[i]为以c开头的库函数
		if(string[i]=='c')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为cos(x)函数
			if(seekStr(string,i,"cos"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=6;
				i--;                     
				continue;  
			}
			//为cosh(x)函数
			if(seekStr(string,i,"cosh"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=7;
				i--;                     
				continue;  
			}
			//为cot(x)函数
			if(seekStr(string,i,"cos"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=8;
				i--;                     
				continue;  
			}
		}//if(string[i]=='c')
		//string[i]为以e开头的库函数
		if(string[i]=='e')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为exp(x)函数
			if(seekStr(string,i,"exp"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=9;
				i--;                     
				continue;  
			}
		}//if(string[i]=='e')
		//string[i]为以f开头的库函数
		if(string[i]=='f')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为exp(x)函数
			if(seekStr(string,i,"floor"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=10;
				i--;                     
				continue;  
			}
		}//if(string[i]=='f')
		//string[i]为以m开头的库函数
		if(string[i]=='m')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为mod(x)函数
			if(seekStr(string,i,"mod"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=11;
				i--;                     
				continue;  
			}
		}//if(string[i]=='m')
		//string[i]为以l开头的库函数
		if(string[i]=='l')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为ln(x)函数
			if(seekStr(string,i,"ln"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=12;
				i--;                     
				continue;  
			}
			//为log(x)函数
			if(seekStr(string,i,"log"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=13;
				i--;                     
				continue;  
			}
		}//if(string[i]=='l')
		//string[i]为以p开头的库函数
		if(string[i]=='p')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为pow(x)函数
			if(seekStr(string,i,"pow"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=14;
				i--;                     
				continue;  
			}
		}//if(string[i]=='p')
		//string[i]为以s开头的库函数
		if(string[i]=='s')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为sin(x)函数
			if(seekStr(string,i,"sin"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=15;
				i--;                     
				continue;  
			}
			//为sinh(x)函数
			if(seekStr(string,i,"sinh"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=16;
				i--;                     
				continue;  
			}
			//为sin(x)函数
			if(seekStr(string,i,"sqrt"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=17;
				i--;                     
				continue;  
			}
		}//if(string[i]=='s')
		//string[i]为以t开头的库函数
		if(string[i]=='t')
		{
			if('0'<=string[i-1] && string[i-1]<='9')  //该函数前为数字
			{              //在该函数入栈stact前加一次对'*'的处理
				while(stack[top].oper=='*' || stack[top].oper=='/'||
				stack[top].flag==2)
				{
				   bolan[j]=stack[top];
				   j++;
				   top--;
				}
			    //将'*'压入栈stact中
		    	top++;
			    stack[top].flag=1;
			    stack[top].oper='*';
			}
			//为tan(x)函数
			if(seekStr(string,i,"tan"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=18;
				i--;                     
				continue;  
			}
			//为tanh(x)函数
			if(seekStr(string,i,"tanh"))   
			{                            //将该函数入栈stact中
				top++;
				stack[top].flag=2;
				stack[top].func=19;
				i--;                     
				continue;  
			}
		}//if(string[i]=='p')
	    
		//判定string[i]=',',将栈stact中'('后的运算符和函数全部弹出,
		//压入数组bolan中,
		if(string[i]==',')
		{
			while(stack[top].oper!='(')
			{
				bolan[j]=stack[top];
				j++;
				top--;
			}
			continue;
		}

		//判定string[i]='x',则用类中未知数变量xx代替,压入数组bolan中 
		if(string[i]=='x')
		{
			bolan[j].flag=0;   //标识为数值
			bolan[j].value=xx;
			j++;
		}
    }

	//转换结束时,若栈stact不为空,则将栈内所有运算符和函数弹出,存入
	//数组bolan中
	while(top!=0)
	{
		bolan[j]=stack[top];
		j++;
		top--;
	}

	//转换结束,在数组bolan尾加一opera='#'作为结束符
    bolan[j].oper='#';

    return 1;
}

//将数字字符串转化成数值
double CMathString::stringToDigital(char *s)
{
	double sum=0,    //转化后的数值
		temp,
		ten=0.1;     //小数变化值
	int i,ch,
		flag=0;    //标识是小数还是整数,0为整数
	for(i=0;s[i]!='\0';i++)
	{
		if(s[i]!='.')
		{
			if(flag==0)  //整数部分
			{
				ch=s[i]-'0';
				sum=sum+ch;
				sum=sum*10;
			}
			else        //小数部分
			{
				ch=s[i]-'0';
				temp=ch*ten;   //小数点移位
				sum=sum+temp;
				ten=ten*0.1;    //改变小数点位置
			}
		}
		else     //小数点
		{
			sum=sum/10;
			flag=1;
		}
	}//for
	if(flag==0)    //无小数部分
		sum=sum/10;
	return sum;

}

//求波兰式bolan的值
//方法如下:
//1.若节点bolan[i]为数值,则如数据栈dataStact
//2.若节点bolan[i]为运算符,则从数据栈dataStact弹出数据进行计算,并
//  将结果压入数据栈dataStact中
//3.若节点bolan[i]为函数,则从数据栈dataStact弹出数据,调用相应的库
//  函数进行计算,并将结果压入数据栈dataStact中
//4.若节点bolan[i]为结束符'#',则数据栈dataStact中的数据弹出,赋给
//  result,并返回0
//返回值:
//1. 计算正确,返回0
//2. 在计算中若除数为0,返回1
//3. 反余弦函数acos(x)中的x不满足条件,返回2
//4. 反正弦函数asin(x)中的x不满足条件,返回3
//5. 余切函数cot(x) 中tan(x)为0,返回4
//6.取模x%y函数mod(x,y)中y为0,返回5
//7.自然对数函数ln(x),如果x<=0,则返回6
//8.取10的对数函数log10(x),如果x<=0,则返回7
//9.开方函数sqrt(x),如果x<0,则返回8
//10.计算中有其他错误,返回-1
int CMathString::compvalue(void)
{
	double  dataStack[MAX/2];   //存放中间数据的数据栈
	int top=0,            //数据栈dataStact的栈顶
		i;              //数组bolan的下标
	for(i=0;bolan[i].oper!='#';i++)
	{
		//节点bolan[i]为数值,则如数据栈dataStact
		if(bolan[i].flag==0)
		{
			top++;
			dataStack[top]=bolan[i].value;
			continue;
		}

		//节点bolan[i]为运算符,则从数据栈dataStact弹出数据进行计算,并
        //将结果压入数据栈dataStact中
		//在计算中若除数为0,返回1
		if(bolan[i].flag==1)
		{
			switch(bolan[i].oper)
			{
			case '+':
				dataStack[top-1]=dataStack[top-1]+dataStack[top];
				top--;
				break;
				
			case  '-':
				dataStack[top-1]=dataStack[top-1]-dataStack[top];
				top--;
				break;

			case '*':
                dataStack[top-1]=dataStack[top-1]*dataStack[top];
				top--;
				break;

			case '/':
				if(dataStack[top]!=0.0)
				{
					dataStack[top-1]=dataStack[top-1]/dataStack[top];
				    top--;
				    break;
				}
				else  //除数为0,返回1
				{
					return 1;
				}
			case '~':      //取负
				dataStack[top]=0-dataStack[top];
				break;
			}//switch
			continue;
		}//if(bolan[i].flag==1)

		//若节点bolan[i]为函数,则从数据栈dataStact弹出数据,调用相应
		//的库函数进行计算,并将结果压入数据栈dataStact中
		if(bolan[i].flag==2)
		{
			switch(bolan[i].func)
			{
			case 1:    //求绝对值函数abs(x)
				dataStack[top]=fabs(dataStack[top]);
				break;

			case 2:    //反余弦函数acos(x)
				if(-1.0<=dataStack[top] && dataStack[top]<=1.0)
				{
				    dataStack[top]=acos(dataStack[top]);
				    break;
				}
				else  //反余弦函数acos(x)中的x不满足条件,返回2
				{
					return 2;
				}

			case 3:   //反正弦函数asin(x)
				if(-1<=dataStack[top] && dataStack[top]<=1)
				{
				    dataStack[top]=asin(dataStack[top]);
				    break;
				}
				else  //反正弦函数asin(x)中的x不满足条件,返回3
				{
					return 3;
				}

			case 4:   //反正切函数atan(x)
				dataStack[top]=atan(dataStack[top]);
				break;

			case 5:  //反余切函数acot(x)
				dataStack[top]=PI/2-atan(dataStack[top]);
				break;

			case 6:   //余弦函数cos(x)
				dataStack[top]=cos(dataStack[top]);
				break;
               
			case 7:    //双曲余弦cosh(x)
				dataStack[top]=cosh(dataStack[top]);
				break;

			case 8:    //余切函数cot(x)   cot(x)=1/tan(x)
				if(tan(dataStack[top])!=0)
				{
					dataStack[top]=1/tan(dataStack[top]);
					break;
				}
				else    //余切函数cot(x) 中tan(x)为0,返回4
				{
					return 4;
				}
				
			case 9:    //e的x次方函数exp(x)
				dataStack[top]=exp(dataStack[top]);
				break;

			case 10:   //求不大于x的最大整数 floor(x)
				dataStack[top]=floor(dataStack[top]);
				break;

			case 11:   //取模x%y函数mod(x,y),即
				if(dataStack[top]!=0)
				{
				   dataStack[top-1]=fmod(dataStack[top-1],dataStack[top]);
				   top--;
				   break;
				}
				else   //取模x%y函数mod(x,y)中y为0,返回5
				{
					return 5;
				}

			case 12:    //自然对数函数ln(x),如果x<=0,则返回6
				if(dataStack[top]>0)
				{          //ln(x)的库函数为log(x)
					dataStack[top]=log(dataStack[top]);
					break;
				}
				else
				{
					return 6;
				}

			case 13:    //取10的对数函数log10(x),如果x<=0,则返回7
				if(dataStack[top]>0)
				{          //log10(x)的库函数为log10(x)
					dataStack[top]=log10(dataStack[top]);
					break;
				}
				else
				{
					return 7;
				}

			case 14:    //x的y次方函数pow(x,y)
				dataStack[top-1]=pow(dataStack[top-1],dataStack[top]);
				top--;
				break;

			case 15:    //正弦函数sin(x)
				dataStack[top]=sin(dataStack[top]);
				break;

			case 16:    //双曲正弦sinh(x)
				dataStack[top]=sinh(dataStack[top]);
				break;

			case 17:   //开方函数sqrt(x),如果x<0,则返回8
				if(dataStack[top]>=0)
				{
					dataStack[top]=sqrt(dataStack[top]);
					break;
				}
				else
				{
					return 8;
				}

			case 18:    //正切函数tan(x)
				dataStack[top]=tan(dataStack[top]);
				break;

			case 19:    //双曲正切函数tanh(x)
				dataStack[top]=tanh(dataStack[top]);
				break;
            }//switch(bolan[i].func)
			continue;
		}//if(bolan[i].flag==2)
	}//for(i=0;bolan[i].oper!='#';i++)
	if(top==1)       //计算正确
	{
		result=dataStack[top];
		return 0;    //返回0
	}
	else           //计算中有其他错误,返回-1
		return -1;   
}

double CMathString::getvalue(void)  //返回计算得到的表达式值
{
	return result;
}