数据结构代码中缀转后缀表达式算法及源代码.docx
《数据结构代码中缀转后缀表达式算法及源代码.docx》由会员分享,可在线阅读,更多相关《数据结构代码中缀转后缀表达式算法及源代码.docx(15页珍藏版)》请在冰豆网上搜索。
数据结构代码中缀转后缀表达式算法及源代码
数据结构代码中缀转后缀表达式算法及源代码
#include
#include
#include
#defineMAX100/*表达式最大长度*/#definetrue1
#definefalse0
/*定义数据栈*/
typedefstructLinkStack1
{
floatdata;
structLinkStack1*next;}LinkStack1,*Top1;ntinitStack1(Top1*t)/*数据栈初始化*/i
{
*t=NULL;
returntrue;
}
intpush1(Top1*t,floatval)/*数据栈插入元素*/
{
Top1p=(Top1)malloc(sizeof(LinkStack1));/*开内存*/
if(p==NULL)
returnfalse;
p->data=val;
p->next=*t;
*t=p;
returntrue;
}
floatgetTop1(Top1*t)/*取数据栈元素*/{
return(*t)->data;}
intpop1(Top1*t,float*val)/*推出数据栈元素并存到*val中*/
{
Top1p=*t;
if(p==0)
returnfalse;
*t=p->next;
*val=p->data;
free(p);/*释放所占内存*/
returntrue;
}
/*定义操作符栈*/
typedefstructLinkStack2{
intdata;
structLinkStack2*next;LinkStack2,*Top2;}
intinitStack2(Top2*t)/*数据栈初始化*/{
*t=NULL;
returntrue;
}
intpush2(Top2*t,charval)/*操作符栈插入元素*/{
Top2p=(Top2)malloc(sizeof(LinkStack2));/*开内存*/
if(p==0)
returnfalse;
p->data=val;
p->next=*t;
*t=p;
returntrue;
}
intgetTop2(Top2*t)/*取操作符栈元素*/{
return(*t)->data;}
intpop2(Top2*t,char*val)
Top2p=*t;
if(p==0)
returnfalse;
*t=p->next;
*val=p->data;
free(p);/*释放所占内存*/
returntrue;
}
/*计算*/
floatcalc(floata,charop,floatb){intd,e;
switch(op)
{
case'+':
returna+b;/*计算+*/
case'-':
returna-b;/*计算-*/
case'*':
returna*b;/*计算**/
case'/':
/*计算/,若被除数为零,报错*/
if(b==0)
{
printf("ErrorDivisoris0\n");
returnfalse;
}
returna/b;
case'%':
/*计算%,若被取余数为零报错*/
d=(int)a;
e=(int)b;
if(e==0)
{
printf("ErrorDivisoris0\n");
returnfalse;
}
return(float)(d%e);
default:
printf("Error!
!
notoprater\n");/*非操作符报错*/
returnfalse;
}
}
/*判断操作符优先级*/
charpriority(chara,charb){
if(a=='='&&b=='\n')return'*';/*'*'表示结束*/
if(a=='('&&b==')')return'#';/*'#'表示左右括号相遇*//*'<'、'>'、'='分别表示优先级:
小于、大于、相等*/
if(a=='=')return'<';
if(b=='\n')return'>';
if(a==')')return'>';
if(a=='(')return'<';
if(b=='(')return'<';
if(b==')'&&a!
='(')return'>';
if((a=='+'||a=='-')&&(b=='/'||b=='*'||b=='%'))return'<';
if((b=='+'||b=='-')&&(a=='/'||a=='*'||a=='%'))return'>';
if((a=='+'||a=='-')&&(b=='+'||b=='-'))return'=';
if((a=='*'||a=='/'||a=='%')&&(b=='*'||b=='/'||b=='%'))return'=';}
/*是否操作符*/
intisOp(charm)
{
if(m=='*'||m=='/'||m=='%'||m=='('||m==')'||m=='+'||m=='-'||m=='\n')
returntrue;
returnfalse;
}
/*中缀变后缀*/
voidInfix(chara[],charb[]){
charc,p,x;
inti=0,j=0;
Top2op;
initStack2(&op);/*初始化操作符栈*/
push2(&op,'=');/*'='作为栈底元素*/
while(a[i]!
='\0')
{
if(!
isOp(a[i]))/*是操作数,直接输出*/
{
b[j++]=a[i];
}
else
{
b[j++]='';/*数字和数字用空格隔开*/
switch(priority(getTop2(&op),a[i]))/*比较两个算符的优先级*/
{
case'<':
push2(&op,a[i]);/*当前算符优先级高,将其入操作符栈*/
break;
case'>':
case'=':
while((priority(getTop2(&op),a[i])=='=')
||(priority(getTop2(&op),a[i])=='>'))
{
pop2(&op,&c);/*当前算符优先级低,则取栈顶*/
b[j++]=c;
}
if(priority(getTop2(&op),a[i])=='<')
push2(&op,a[i]);/*出栈*/
else
{
if(priority(getTop2(&op),a[i])=='#')
{
pop2(&op,&c);/*当前算符优先级低,则取栈顶*/
i++;
break;
}
elsebreak;
}
break;
case'#':
/*左右括号相遇,则推出栈顶,并原表达式数组下标加1*/
pop2(&op,&c);
i++;
break;
case'*':
/*结束*/
break;
}
}
i++;
}
if(a[i]=='\0')
{
while(op->data!
='=')/*字符栈元素全都放到b数组中*/
{
pop2(&op,&p);
b[j++]=p;
i++;
}
for(i=0;iprintf("%c",b[i]);
}
b[j]='\0';/*为字符数组置结束标志*/
}
/*将数字字符转变成相应的数*/
floatcharToNum(chara[],int*i){
floatx=0.0;
intk=0;
while(a[*i]>='0'&&a[*i]<='9')/*整数部分*/
{
x=x*10+a[*i]-'0';
(*i)++;
}
if(a[*i]=='.')/*小数部分*/
{
(*i)++;
while(a[*i]>='0'&&a[*i]<='9')
{
x=x*10+a[*i]-'0';
(*i)++;
k++;/*记录多少小数位数*/
}
}
while(k!
=0)
{
x=x/10;
k=k-1;
}
returnx;
}
/*第一种:
后缀表达式计算*/
floatthe_fir_Exp(charc[])
{
inti=0;
floata,b,n;
Top1dig;
initStack1(&dig);/*初始化操作数栈*/
push1(&dig,0);
while(c[i]!
='\0')/*为表达式的结束标志*/
{
if(!
isOp(c[i])&&c[i]!
='')/*为操作数*/
{
n=charToNum(c,&i);
i=i-1;/*转换后i值应该减一否则丢掉一个字符*/
push1(&dig,n);
}
elseif(isOp(c[i]))/*为操作符*/
{
pop1(&dig,&a);/*取一操作数*/
pop1(&dig,&b);/*取另一操作数*/
push1(&dig,(calc(b,c[i],a)));/*计算,并压入栈*/
}
i++;
}
returngetTop1(&dig);
}
/*第二种计算方法*/
floatthe_sec_Exp(chara[]){
inti=0,j;
charb[MAX],c;
floatm,n;
Top2op;
Top1dig;
initStack2(&op);/*初始化操作符栈*/
push2(&op,'=');
initStack1(&dig);/*初始化操作数栈*/
push1(&dig,0);
while(a[i]!
='\0')
{
if(!
isOp(a[i]))/*是操作数*/
{
j=0;
for(;!
isOp(a[i])&&a[i]!
='\0';i++)
b[j++]=a[i];
b[j]='+';/*‘+’结束*/
j=0;
push1(&dig,(charToNum(b,&j)));/*转换,并压入栈*/
}
else
{
switch(priority(getTop2(&op),a[i]))/*比较两个算符的优先级*/
{
case'<':
push2(&op,a[i]);i++;
break;
case'>':
case'=':
pop2(&op,&c);/*取出操作符*/
pop1(&dig,&m);/*取一操作数*/
pop1(&dig,&n);/*取另一操作数*/
push1(&dig,(calc(n,c,m)));/*计算,并压入栈*/
break;
case'#':
pop2(&op,&c);
i++;
break;
case'*':
break;
}
}
}
pop2(&op,&c);/*取出操作符*/
while(c!
='=')/*‘=’为操作符栈的结束标志*/
{
pop1(&dig,&m);/*取一操作数*/
pop1(&dig,&n);/*取另一操作数*/
push1(&dig,(calc(n,c,m)));/*计算,并压入栈*/
pop2(&op,&c);/*取出操作符*/
}
returngetTop1(&dig);/*返回值为数字栈栈顶*/}
/*主函数*/
voidmain()
{
loop:
/*确定再次输入数据计算,及输入错误时循环*/
{
inti,k,j;
intz[MAX],y[MAX];
chara[MAX]={""},b[MAX],ch;
floatm;
z[MAX]="";y[MAX]="";/*初始化a[]/,z[],y[]*/
printf("\nInput:
");
scanf("%s",&a);/*输入表达式*/
/*容错四种情况*/
for(i=0;a[i]!
='\0';i++)
{
if(!
(a[i]>='0'&&a[i]<='9'||isOp(a[i])||a[i]=='.'))/*1非数字、小数点和操作符*/
{
printf("------");
for(j=0;j
printf("-");
printf("^\n");
printf("inputwrong!
!
!
intputagain.\n");
gotoloop;
}
if(i>=MAX-1)/*2表达式越界*/
{
printf("inputtoolong!
!
!
intputagain.\n");
gotoloop;
}
}
for(i=0,j=0,k=0;a[i]!
='\0';i++)
{
if(a[i]=='(')z[k++]=i;/*z[k]为记录'('的位置k表示(的数目*/
if(a[i]==')')y[j++]=i;/*y[k]为记录')'的位置y表示)的数目*/
}
if(k!
=j)/*3左右括号不相等*/
{
printf("------");
if(k>j)
{for(i=0;iprintf("-");}
else
if(k{for(i=0;iprintf("-");}
printf("^\n");
printf("inputwrong!
!
!
theNO.of'('!
=')'intputagain:
\n");
gotoloop;
}
k=0;j=0;i=0;
for(;a[i]!
='\0';i++)/*4左括号在右括号右面*/
{
if(z[k++]>y[j++])
{
printf("------");
for(i=0;iprintf("-");
printf("^\n");
printf("inputwrong!
!
!
')'firstthen'('intputagain:
\n");
gotoloop;
}
}
/*中缀变后缀,再计算*/
printf("postfixexpressionsis:
");
Infix(a,b);/*中缀变后缀*/
m=the_fir_Exp(b);/*后缀表达式计算*/
printf("\nthefirstmethodresultis:
%lf\n",m);
/*直接计算*/
m=the_sec_Exp(a);
printf("thesecondmethodresultis:
%lf\n",m);
/*是否再次输入数据计算*/
printf("again?
(yorn)\ninput:
");
loop_1:
{
ch=getch();
if(ch=='y')/*y再次输入*/
gotoloop;
elseif(ch=='n')/*n退出*/
exit(0);
else/*都不是提示输入错误*/
{
printf("\ninputwrong!
againplease!
!
!
\ninput:
");
gotoloop_1;
}
}
getch();
}
}