fun_bolan.cpp

来自「本程序是完成一个函数计算器的功能,通过输入表达式,然输入表达的未知数,则可以计算」· C++ 代码 · 共 776 行 · 第 1/2 页

CPP
776
字号
					string[i+1]=='-' ||
					string[i+1]=='*'|| 
					string[i+1]=='/' || 
					string[i+1]=='\0'|| 
					string[i+1]==')'|| 
					string[i+1]=='#')
				{
					bolan[j].value = string[i];              //存入表达式中未知数
					bolan[j].flag = 0 ;//标识该节点为未知数
					j++;
					befordigit = 0 ;
					continue ;
				}
				else  //是以p开头的库函数
				{
					if(CheckFuncName(string ,i , "pow")&& string[i+1]>='a'&& string[i+1] <= 'z')   //为pow(x,y)函数,并将其入栈stack中
					{
						top++ ; 
						stack[top].flag = 2 ; 
						stack[top].func = 17 ;
						i-- ;    //因为在CheckFuncName函数中
						befordigit = 1 ;
						continue ; // i = i+strlen("pow") , i 已指向函数的下一个字符 , 所以要减1
					}
				}
			}//if(string[i] == 'p')
			if(string[i] =='b' || string[i] =='d' || string[i] =='g'  || string[i] =='h'
				||string[i] =='i' || string[i] =='j' ||  string[i] =='k' || string[i] =='n' ||
				string[i] =='o' || string[i] =='q' || string[i] =='r' || string[i] =='u' ||
				string[i] =='v' || string[i] =='w' || string[i] =='x' || string[i] =='y' ||
				string[i] =='z')
			{
					bolan[j].value = string[i];              //存入表达式中未知数
					bolan[j].flag = 0 ;//标识该节点为未知数
					j++;
					befordigit = 0 ;
					continue ;
			}
		}
		else 
		{
			if(string[i] == 'P')
			{
				bolan[j].value = string[i];              //存入表达式中常量
				bolan[++j].value = string[++i] ;
				bolan[j].flag = 3 ;//标识该节点为常量
				j++ ;
				befordigit = 0 ;
				continue ;
			}
			//判定为'(',将此'('压入栈
	    	//若'('前为数字,则在'('前加一对'*'的处理
			if(string[i] == '(')
			{
				if(befordigit == 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--;  //将左括号'('弹出
				befordigit = 1 ;
				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 ='~' ;
					befordigit = 1 ;
					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] ; 
					befordigit = 1 ;
					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] ;
				befordigit = 1 ;
				continue ;
			}
			//判定string[i]=',',将栈stact中'('后的运算符和函数全部弹出,
			//压入数组bolan中,
			if(string[i]==',')
			{
				while(stack[top].oper!='(')
				{
					bolan[j]=stack[top];
					j++;
					top--;
				}
				continue;
			}
		}
	}
	/*转换结束时,若栈stact不为空,则将栈内所有运算符和函数弹出,存入数组bolan中*/
	while(top!=0)
	{
		bolan[j]=stack[top];
		j++;
		top--;
	}		
	//转换结束,在数组bolan尾加一opera='#'作为结束符
    bolan[j].oper='#';

    return 1;
}

//求波兰式bolan的值
//方法如下:
//1.若节点bolan[i]为未知数,输入数字,并存入数据栈dataStact
//2.若节点bolan[i]为运算符,则从数据栈dataStact弹出数据进行计算,并
//  将结果压入数据栈dataStact中
//3.若节点bolan[i]为函数,则从数据栈dataStact弹出数据,调用相应的库
//  函数进行计算,并将结果压入数据栈dataStact中
//4.若节点bolan[i]为结束符'#',则数据栈dataStact中的数据弹出,赋给
//  result,并返回0
//返回值:
//1. 计算正确,返回0
//2. 反余弦函数acos(x)中的x不满足条件,返回1
//3. 反正弦函数asin(x)中的x不满足条件,返回2
//4.取模x%y函数modf(x,y)中y为0,返回3
//5.自然对数函数log(x),如果x<=0,则返回4
//6.取10的对数函数log10(x),如果x<=0,则返回5
//7.开方函数sqrt(x),如果x<0,则返回6
//8.除数不能为0   如果y=0 , 则返回7
//9.计算中有其他错误,返回-1
int CalcMain(void)
{
	double  dataStack[MAX/2];   //存放中间数据的数据栈
	int top=0,            //数据栈dataStact的栈顶
		i;              //数组bolan的下标
	double UknowDigit; //存放要未知数字符串
	printf("Analizeing ......\n");
	for(i=0;bolan[i].oper!='#';i++)
	{
		//节点bolan[i]为数值,则如数据栈dataStact
		if(bolan[i].flag==0)
		{
			top++;
			printf("Please input value of %c\n" , bolan[i].value);      
			printf(">%c=" , bolan[i].value);
			scanf("%lf",&UknowDigit);                           // 输入未知数的数值
			dataStack[top]=UknowDigit;
			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 7;
				}
			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:    //反余弦函数acos(x)
					if(-1.0<=dataStack[top] && dataStack[top]<=1.0)
					{
					  dataStack[top]=acos(dataStack[top]);
					  break;
					}
					else  //反余弦函数acos(x)中的x不满足条件,返回1
					{
						return 1;
					}
				case 2:   //反正弦函数asin(x)
					if(-1<=dataStack[top] && dataStack[top]<=1)
					{
					  dataStack[top]=asin(dataStack[top]);
					  break;
					}
					else  //反正弦函数asin(x)中的x不满足条件,返回2
					{
						return 2;
					}
				case 3:   //反正切函数atan(x)
					dataStack[top]=atan(dataStack[top]);
					break;
				case 4:   //反正切函数atan2(y,x)
					dataStack[top-1]=atan2(dataStack[top-1],dataStack[top]);
				    top--;
				    break;
				case 5:   //余弦函数cos(x)
					dataStack[top]=cos(dataStack[top]);
					break;
				case 6:    //正弦函数sin(x)
					dataStack[top]=sin(dataStack[top]);
					break;
				case 7:    //正切函数tan(x)
					dataStack[top]=tan(dataStack[top]);
					break;
				case 8:    //双曲余弦cosh(x)
					dataStack[top]=cosh(dataStack[top]);
					break;
				case 9:    //双曲正弦sinh(x)
					dataStack[top]=sinh(dataStack[top]);
					break;
				case 10:    //双曲正切函数tanh(x)
					dataStack[top]=tanh(dataStack[top]);
					break;
				case 11:    //e的x次方函数exp(x)
					dataStack[top]=exp(dataStack[top]);
					break;
				case 12:    //把x分成尾数和指数 frexp(x,eptr)	

					int doubletoint;
					doubletoint =(int)dataStack[top];
					dataStack[top]=frexp(dataStack[top-1],&doubletoint);
					top--;
					break ;
				case 13 : //返回x*2的n幂  ldexp(x,n)
					dataStack[top]=ldexp(dataStack[top-1],(int)dataStack[top]);
					top-- ;
					break ;
				case 14:    //取对数函数log(x),如果x<=0,则返回4
					if(dataStack[top]>0)
					{          //log(x)的库函数为log(x)
						dataStack[top]=log(dataStack[top]);
						break;
					}
					else
					{
						return 4;
					}
				case 15 :   //取10的对数     log10(x)     如果x<=0,则返回5       
					if(dataStack[top]>0)
					{          //log10(x)的库函数为log10(x)
						dataStack[top]=log10(dataStack[top]);
						break;
					}
					else
					{
						return 5;
					}
				case 16:   //取模x%y函数modf(x,y),即
					if(dataStack[top]!=0)
					{
					   dataStack[top-1]=modf(dataStack[top-1],&dataStack[top]);
					  top--;
					  break;
					}
					else   //取模x%y函数modf(x,y)中y为0,返回3
					{
						return 3;
					}
				case 17:    //x的y次方函数pow(x,y)
					dataStack[top-1]=pow(dataStack[top-1],dataStack[top]);
					top--;
					break;
				case 18:   //开方函数sqrt(x),如果x<0,则返回6
					if(dataStack[top]>=0)
					{
						dataStack[top]=sqrt(dataStack[top]);
						break;
					}
					else
					{
						return 6;
					}
				case 19:  //不小于x的最大整数 ceil(x)
					dataStack[top] = ceil(dataStack[top]);
					break ;
				case 20:    //求绝对值函数fabs(x)
					dataStack[top]=fabs(dataStack[top]);
					break;
				case 21:   //求不大于x的最大整数 floor(x)
					dataStack[top]=floor(dataStack[top]);
					break;
				case 22:   //取模x%y函数fmod(x,y),即
				if(dataStack[top]!=0)
				{
				   dataStack[top-1]=fmod(dataStack[top-1],dataStack[top]);
				   top--;
				   break;
				}
				else   //取模x%y函数fmod(x,y)中y为0,返回3
				{
					return 3;
				}
            }//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;  
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?