数据结构代码中缀转后缀表达式算法及源代码.docx
《数据结构代码中缀转后缀表达式算法及源代码.docx》由会员分享,可在线阅读,更多相关《数据结构代码中缀转后缀表达式算法及源代码.docx(14页珍藏版)》请在冰豆网上搜索。
数据结构代码中缀转后缀表达式算法及源代码
#include
#include
#include
#defineMAX100/*表达式最大长度*/
#definetrue1
#definefalse0
/*定义数据栈*/
typedefstructLinkStack1
{
floatdata。
structLinkStack1*next。
}LinkStack1,*Top1。
intinitStack1(Top1*t>/*数据栈初始化*/
{
*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>>。
/*开内存*/b5E2RGbCAPif(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">。
/*非操作符报错*/p1EanqFDPwreturnfalse。
}
}
/*判断操作符优先级*/
charpriority(chara,charb>
{
if(a=='='&&b=='\n'>return'*'。
/*'*'表示结束*/if(a=='('&&b=='>'>return'#'。
/*'#'表示左右括号相遇*/DXDiTa9E3d
/*'<'、'>'、'='分别表示优先级:
小于、大于、相等*/
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'<'。
RTCrpUDGiT
if((b=='+'||b=='-'>&&(a=='/'||a=='*'||a=='%'>>return'>'。
5PCzVD7HxAif((a=='+'||a=='-'>&&(b=='+'||b=='-'>>return'='。
if((a=='*'||a=='/'||a=='%'>&&(b=='*'||b=='/'||b=='%'>>return'='。
jLBHrnAILg
}
/*是否操作符*/
intisOp(charm>
{
if(m=='*'||m=='/'||m=='%'||m=='('||m=='>'||m=='+'||m=='-'||m=='\n'>xHAQX74J0Xreturntrue。
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]>>/*比较两个算符地优先级*/LDAYtRyKfE{
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!
='='>/*字符栈元素全都放到
{pop2(&op,&p>。
b[j++]=p。
i++。
}
for(i=0。
ii++>/*输出后缀表达式*/
printf("%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。
}
b数组中*/
*/
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]!
='\O'。
i++>
{
*/Zzz6ZB2Ltk
if(!
(a[i]>='0'&&a[i]<='9'||isOp(a[i]>||a[i]=='.'>>/*1非数字、小数点和操作符{
printf("">。
for(j=0。
j
j++>
printf("-">。
printf("人\门">。
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表示)地数目*/dvzfvkwMI1
}
if(k!
=j>/*3左右括号不相等*/
{
printf("">。
if(k>j>
{for(i=0。
ii++>printf("-">。
}
else
if(k
{for(i=0。
ii++>printf("-">。
}printf("A\n">。
printf("inputwrong!
!
!
theNO.of'('!
='>'intputagain:
\n">。
rqyn14ZNXIgotoloop。
}k=0。
j=0。
i=0。
for(。
a[i]!
='\O'。
i++>/*4左括号在右括号右面*/
{
if(z[k++]>y[j++]>
{printf("">。
for(i=0。
ii++>
printf("-">。
printf("A\n">。
EmxvxOtOco
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(>。
}
}