之前在网上找了好多相似的文章,不过有的是功能不够,无法实现多级括号,有的是用到了栈,代码对于初学者来说不好理解。所以自己写了一个。不过不是完整代码,但是能够很好的解释这个逻辑
#include<stdio.h>
#include<string.h>
char * symble(char *a);
float mix(float *x,char *a);
int divide(float *p,char *c);
float index[30];
float *p;
char *c;
char sym[50];
int e=0;
int main()
{
printf("请输入表达式\n");
scanf("%s",c);
e=divide(p,c);
printf("%5.2f\n",mix(p,symble(c)));
}
int divide(float *p,char *c)
{
int i,j=0,m=0;
int t = 0;
float number=0;
for(i=0;*(c+i)!='\0';i++){
if(*(c+i)>='0'&&*(c+i)<='9'){
number=number*10+(*(c+i)-'0');
}
if(*(c+i)=='.')
{
m=0;
i++;
while(*(c+i)>='0'&&*(c+i)<='9')
{
number=number*10+(*(c+i)-'0');
m++;
i++;
}
for(int a=0;a<m;a++)
{
number=number/10;
}
}
if(*(c+i)=='+'||*(c+i)=='-'||*(c+i)=='*'||*(c+i)=='/'||*(c+i+1)=='\0'){
*(p+j)= number;
j++;
t++;
number=0;
}
}
return t;
}
char * symble(char *a)
{
int j=0;
for(int i=0;*(a+i)!='\0';i++){
if(*(a+i)=='+'||*(a+i)=='-'||*(a+i)=='*'||*(a+i)=='/'||*(a+i)=='('||*(a+i)==')'){
sym[j]=*(a+i);
j++;
}
}
sym[j]='\0';
return sym;
}
float mix(float *x,char *a)
{
c=a;
p=x;
float asd[30];
char zxc[30];
int d=0,f=0;
int flag=0;
while(*c!='\0'&&flag==0)
{
switch(*c)
{
case '+':{
asd[d]=*p;
zxc[d]=*c;
d++;
p++;
f++;
break;
}
case '-':{
asd[d]=*p;
zxc[d]=*c;
d++;
p++;
f++;
break;
}
case '*':{
if(*(c+1)=='(')
{
float g=*p;
c+=2;
p++;
float w=mix(p,c);
*p=w*g;
continue;
break;
}
*p=(*p)*(*(p+1));
f++;
for(int i=1;i<e-f;i++)
{
*(p+i)=*(p+i+1);
}
break;
}
case '/':{
if(*(c+1)=='(')
{
float g=*p;
c+=2;
p++;
float w=mix(p,c);
*p=g/w;
continue;
break;
}
if(*(p+1)==0)
{
printf("除数不能为0,请重试!!!\n");
return -1;
}
*p=(*p)/(*(p+1));
f++;
for(int i=1;i<e-f;i++)
{
*(p+i)=*(p+i+1);
}
break;
}
case '(':{
c++;
float w=mix(p,c);
*p=w;
continue;
break;
}
case ')':{
flag=1;
break;
}
}
c++;
}
asd[d]=*p;
float result=asd[0];
for(int i=0;i<d;i++)
{
switch(zxc[i])
{
case '+':{
result=result+asd[i+1];
break;
}
case '-':{
result=result-asd[i+1];
break;
}
}
}
return (result);
}
简单说一下比较难理解的地方:
首先,如果要实现多级括号,那么必定要使用递归,但解析刚开始输入的字符串只需要一次,所以分别用divide和symble去解析输入的表达式然后把解析出来的浮点型数组和字符数组传到分析函数中。
遇到加减、乘除、括号时不同的处理方式:
由于加减和乘除运算优先级不同,所以处理的时候需要先处理乘除,再计算加减,程序中的全局数组用于第一次处理(处理乘除),函数内部的数组用于第二次处理(加减处理);