当前位置: 代码迷 >> C语言 >> [原创]用复合链表和栈外理四则运算
  详细解决方案

[原创]用复合链表和栈外理四则运算

热度:217   发布时间:2007-06-28 17:45:47.0
[原创]用复合链表和栈外理四则运算

#include<stdio.h>
#include<malloc.h>
union nuionnum
{
double num1;
char num2;
};
struct lianbiao
{
struct lianbiao *p;
union nuionnum num;
int flage;//标志是数字还是符号

};
void main()
{
char c;
struct lianbiao lianhe;
struct lianbiao *next;
printf("请输入一个计算机能识别的四则运算表达式,如:a+b*(c+d)/e\n");
while(1)
{
first:
next=&lianhe;
while((int)(c=getchar())!=10)
{
loop:
//将表达式放入复合链表中
if (c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
{
next->num.num2=c;
if (c== '+' || c== '-' )
next->flage =1;
else if(c== '*' ||c== '/' )
next->flage =2;
else if(c== '(' )
next->flage =3;
else if(c== ')' )
next->flage =4;
next->p=calloc(1,sizeof(struct lianbiao));
next=next->p;
next->p=NULL;
}
else if(c>='0'&&c<='9')
{ long int t=1;
int flag=0;
next->num.num1=c-48;
while(((c=getchar())>='0'&&c<='9')||c=='.')
{
if (flag==1 && c!='.')
{
t=t*10;
next->num.num1=next->num.num1+(c-48.0)/t;
}
else if(c>='0'&&c<='9')
next->num.num1=next->num.num1*10+c-48;

if (c=='.')
{
flag=1;
}
}
next->flage =0;
next->p=calloc(1,sizeof(struct lianbiao));
next=next->p;
next->p=NULL;
if (c=='\n')break;
goto loop;
}
else
{
printf("不是合法的算术表达式!!!\n请重新输入:\n");
while(getchar()!='\n');//设置重新输入
goto first;
}
}
//将链表中的数字和符号分别入栈
next=&lianhe;
{
int i=0,j=0;//用来标记栈的顶点
double arrd[100];
char arrc[2][100];
while(next->p!=NULL)
{
if (next->flage !=0&&next->num.num2==')')//括号的外理
{
while(arrc[0][i-1]!='(')//出栈
{
if (arrc[0][i-1]=='+')
{
arrd[j-2]=arrd[j-2]+arrd[j-1];
i=i-1;
j=j-1;
}
else if(arrc[0][i-1]=='-')
{
arrd[j-2]=arrd[j-2]-arrd[j-1];
i=i-1;
j=j-1;
}
else if(arrc[0][i-1]=='*')
{
arrd[j-2]=arrd[j-2]*arrd[j-1];
i=i-1;
j=j-1;
}
else if(arrc[0][i-1]=='/')
{
arrd[j-2]=arrd[j-2]/arrd[j-1];
i=i-1;
j=j-1;
}
}
i=i-1;
}
else if (next->num.num2 =='(')//入栈
{
arrc[1][i]=next->flage;
arrc[0][i]=next->num.num2;
i++;
}
else if (next->flage !=0)//对运算复符的理
{
front:
if (i>0&&next->flage<arrc[1][i-1]&&arrc[1][i-1]!=3)
{
if (arrc[0][i-1]=='*')
{
arrd[j-2]=arrd[j-2]*arrd[j-1];
i=i-1;
j=j-1;
}
else if(arrc[0][i-1]=='/')
{
arrd[j-2]=arrd[j-2]/arrd[j-1];
i=i-1;
j=j-1;
}
goto front;
}
arrc[1][i]=next->flage;
arrc[0][i]=next->num.num2;
i++;
}
else
{
arrd[j]=next->num.num1; //对数字的理
j++;
}
next=next->p;
}
while(i!=0)//全部入栈之后对椎的外理
{
if (arrc[0][i-1]=='+')
{
arrd[j-2]=arrd[j-2]+arrd[j-1];
i=i-1;
j=j-1;
}
else if (arrc[0][i-1]=='-')
{
arrd[j-2]=arrd[j-2]-arrd[j-1];
i=i-1;
j=j-1;
}
else if (arrc[0][i-1]=='*')
{
arrd[j-2]=arrd[j-2]*arrd[j-1];
i=i-1;
j=j-1;
}
else if(arrc[0][i-1]=='/')
{
arrd[j-2]=arrd[j-2]/arrd[j-1];//1+2*3/4+5 1 1.5 5 ++
i=i-1;
j=j-1;
}
}
printf("%lf\n",arrd[0]);

}
}
}

搜索更多相关的解决方案: 链表  运算  复合  

----------------解决方案--------------------------------------------------------

顶个


----------------解决方案--------------------------------------------------------
谢了版主.
----------------解决方案--------------------------------------------------------

版主,我上面的程序有个地方不太好,想问一下用scanf()函数输入时能不能判断到了你输入的数据的未尾??如输入一条表达式.
用getchar()!='\n'可能但只能输入字符不能输入其它数据
有人说用while(scanf("%lf",&a)!=EOF)但我用不行.


----------------解决方案--------------------------------------------------------
顶下,了不起
----------------解决方案--------------------------------------------------------