📄 表达式.cpp
字号:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<malloc.h>
#define max 100
//********************************************************
double tran_num(char c[],int *i); //把数字字符转化成浮点型数字
void postfix_ex(char a[],char opr[]); //求后缀表达式
int grade(char c); //返回运算符号的优先等级
int find(char x[],char y); //数组元素查找
float count(char a[]); //求后缀表达式的值
float div(float x,float y); //除法
float sqr(float x); //开方
float power(float x,float y); //乘方
float fac(float x); //阶乘
float arrange(float x,float n); //排列
float combin(float x,float n); //组合
int match_chara(char b[]); //括号匹配
int il_chara(char b[]); //检查非法字符
//********************************************************
struct stack
{
int top;
char a[max];
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%栈的操作%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void InitStack(struct stack *t) //初始化栈
{
t->top=-1;
}
void pop(struct stack *t) //元素出栈
{
if(-1 < t->top && t->top < max)
t->top--;
}
void push( struct stack *t,char x) //元素进栈
{
if(-1<=t->top && t->top<max-1)
{
t->top++;
t->a[t->top]=x;
}
}
char gettop( struct stack *t) //取栈顶元素
{
if(-1<t->top&&t->top<max)
return(t->a[t->top]);
else
return(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%工具函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float div(float x,float y) //除法运算
{
if(y==0)
{
printf("除数不能为0\n");
}
else
return (x/y);
}
float sqr(float x) //开平方运算
{
if(x<0)
printf("被开方数不能小于零\n");
else
return ( (float)sqrt(x) );
}
float power(float x,float y) //乘方运算
{
int i;
float sum=1.00000;
if(x==0)
printf("乘方的底数不为零\n");
else if(y>0)
{
for(i=1;i<=y;i++)
sum=sum*x;
return(sum);
}
else if(y==0.0)
return(sum);
else
{for(i=1;i<=y;i++)
sum=sum*x;
return( (float)1.0/sum);
}
}
float fac(float x) //阶乘运算
{
int i;
float sum=1.0;
if(x==0)
return(sum);
if(x>0)
{
for(i=1;i<=x;i++)
sum=sum*i;
return(sum);
}
if(x<0)
printf("阶乘的的基数不为负数\n");
}
float arrange(float x,float n) //排列运算
{
float i;
float sum=1.0;
if(x>n)
printf("排列的上指数不能大于下指数\n");
else if(x==n)
return( fac(x));
else
for(i=n+1-x;i<=n;i++)
sum=i*sum;
return(sum);
}
float combin(float x,float n) //组合运算
{
float sum;
if(x>n)
printf("排列的上指数不能大于下指数\n");
else if(x==n)
return(1.0);
else
sum=arrange(x,n)/fac(x);
return(sum);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%运算符优先级判定函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int grade(char c)
{
if(c=='#')
return(-1);
if(c=='(')
return(0);
if(c=='+'||c=='-')
return(1);
if(c=='*'||c=='/')
return(2);
if(c=='!'||c=='^'||c=='A'||c=='a'||c=='S'||c=='s'||c=='C'||c=='c')
return(3);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int il_chara(char b[]) //检查表达式子中是否有非法字出现
{
char s[22]={"()[]{}!^ACSacs+-/*.,"};
int i=0,k=-1,j; //k的值用来标志表达式中的字符是否和数组s中的元素相等
while(b[i]!='\0')
{
if('9'<b[i]||b[i]<'0')
{
for(j=0;j<22;j++)
if(b[i]!=s[j])
continue;
else k=j;
if(k==-1) //如果k的数值还是为初始值,那么就有非法字出现
{
printf("表达式中有非法字符出现\n");
return(0);
break;
}
else
return(1);
}
i++;
k=-1;
}
}
int match_chara(char b[]) //检查表达式子中的括号是否配对
{
int i=0,j=0;
struct stack *s;
s=(struct stack *) malloc(sizeof(struct stack));
InitStack(s);
while(b[i]!='\0')
{
switch(b[i])
{
case'(':push(s,b[i]); //遇到左括号进栈
break;
case'[':push(s,b[i]);
b[i]='(';
break;
case'{':push(s,b[i]);
b[i]='(';
break;
case')':if(gettop(s)=='(') pop(s); //遇到右括号出栈
else
{
printf("括号不匹配\n");
return(0);
}
break;
case']':
if(gettop(s)=='[') pop(s);
else
{
printf("括号不匹配\n");
b[i]=')'; // 并把相应的大中括号改成小括号
return(0);
break;
}
case'}':
if(gettop(s)=='{') pop(s);
else
{
printf("括号不匹配\n");
b[i]=')';
return(0);
break;
}
}
i++;
}
if(s->top!=-1) //如果栈为空说明括号匹配否则不匹配
{
printf("数学表达式括号不匹配\n");
return(0);
}
else
return(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double tran_num(char c[],int *i) //将数字的字符串转化为实数
{
int k=0,j=0;
double sum1=0.0,sum2=0.0;
while(c[*i]>='0'&&c[*i]<='9'||c[*i]=='.')
{
if('0'<=c[*i]&&c[*i]<='9')
{
sum1=sum1*10.0+(c[*i]-48); //sum1纪录整数部分
(*i)++;
}
else
{
(*i)++;
while('0'<=c[*i]&&c[*i]<='9')
{
k++; //k用来纪录小数的位数
sum2=sum2*10+(c[*i]-48);
(*i)++;
}
while(j<k) //sum2纪录小数部分
{
sum2=sum2/10.0;
j++;
}
}
}
return (sum1+sum2);
}
int find(char x[],char y) //查找数组x中是否存在y
{
int i=0;
while(x[i]!='\0')
{
if(x[i]==y)
return(1);
else
i++;
}
}
//&&&&&&&&&&&&&&&&&&&&&&求后缀表达式函数%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void postfix_ex(char a[],char opr[])
{
int i=0,top=0;
char x[]={"+*-/aAcCSs!^"}; //数组x中存所有可能出现的运算符
struct stack *s;
s=(struct stack *) malloc(sizeof(struct stack));
InitStack(s);
push(s,'#'); //用#标志运算完成
while(a[i]!='\0')
{
if((a[i]>='0'&&a[i]<='9')||a[i]=='.')
{
opr[top]=a[i];
top++;
}
else if(find(x,a[i])==1||a[i]==',') //当遇到运算符号或逗号 就空格赋给后缀数组
{
opr[top]=' ';
top++;
if(find(x,a[i])==1)
{
if(grade(a[i])>grade(s->a[s->top])) //当表达式中运算符等级高于栈顶元素
push(s,a[i]); //运算符进栈
else
{
while(grade(a[i])<=grade(s->a[s->top])) //当表达式中运算符等级不高于栈顶元素
{
opr[top]=gettop(s); //栈顶运算符进后缀数组
top++;
pop(s);
}
push(s,a[i]); //把原表达式中的运算符进栈
}
}
}
else if(a[i]=='(')
push(s,'(');
else if(a[i]==')') //当遇到右括号时,把和该右括号
{
while(s->a[s->top]!='(') //配对的左括号之间的运算号出栈且赋给后缀数组
{
opr[top]=gettop(s);
top++;
pop(s);
}
pop(s); //把左括号也出栈
}
i++;
}
while((s->top)!=0) //当运算符栈不为空时
{
opr[top]=gettop(s); //依次把栈里的运算符放进后缀数组
top++;
pop(s);
}
opr[top]='\0'; //给缀数组加上结束符以便以字符串输出
}
//%—%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float count(char a[])
{
int i=0,top=-1;
float x,op[50];
while(a[i]!='\0')
{
if(a[i]>='0'&&a[i]<='9')
{
++top;
op[top]=(float)tran_num(a,&i); //把数字字符串转化成实数
}
else if(a[i]=='+')
{
x=op[top];
top--;
op[top]=x+op[top];
i++;
}
else if(a[i]=='-')
{
x=op[top];
top--;
op[top]=op[top]-x;
i++;
}
else if(a[i]=='*')
{
x=op[top];
top--;
op[top]=x*op[top];
i++;
}
else if(a[i]=='/')
{
x=op[top];
top--;
op[top]=div(op[top],x);
i++;
}
else if(a[i]=='!')
{
x=op[top];
op[top]=fac(x);
i++;
}
else if(a[i]=='s'||a[i]=='S')
{
x=op[top];
op[top]=sqr(x);
i++;
}
else if(a[i]=='^')
{
x=op[top];
top--;
op[top]=power(op[top],x);
i++;
}
else if(a[i]=='a'||a[i]=='A')
{
x=op[top];
top--;
op[top]=arrange(x,op[top]);
i++;
}
else if(a[i]=='c'||a[i]=='C')
{
x=op[top];
top--;
op[top]=combin(x,op[top]);
i++;
}
else i++;
}
return(op[top]);
}
int main(void)
{
float y;
int p,q;
char b[max];
char e[max];//{"35.5+a((a(3,2)+2),2)+(c(3,1))!-c(5,4)*2+(5^(c(3,1)))/1.25"};
printf("***************************************************************\n");
printf("* 制作时间:2006年12月 *\n");
printf("* 制作人:廖过房,2004051686 *\n");
printf("* 欢迎使用此系统,此系统能完成简单的表达式的求值计算. *\n");
printf("***************************************************************\n");
printf("为了能正确用此系统,请使用前阅读输入格式:\n");
printf("##############################################################\n");
printf("# 开方:s(a)----乘方:a^n----阶乘:a! #\n");
printf("# 排列a(m,n) 其中n<=m----组合c(m,n) 其中 n<=m #\n");
printf("##############################################################\n");
l: printf("注意:请输入表达式后按回车以示结束,表达式不要有空格,结束时不用加"=",\n");
printf("请输入表达式(若要退出请输入EXIT):");
scanf("%s",e);
while(strcmp(e,"EXIT")!=0)
{
printf("原表达式:%s\n",e);
p=il_chara(e); //p的值是1说明没有非法字符
q=match_chara(e); //q的值是1说明括号匹配
if(p==1&&q==1)
{
postfix_ex(e,b);
printf("后缀表达式:%s\n",b);
y=count(b);
printf("表达式的值:%f\n",y);
}
else
{
printf("请重新输入:\n");
goto l;
}
printf("\n\n请输入表达式(若要退出请输入EXIT):");
scanf("%s",e);
}
printf("谢谢使用本系统,你已经成功退出!\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -