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 + -
显示快捷键?