数据结构代码中缀转后缀表达式算法及源代码.docx
- 文档编号:11521529
- 上传时间:2023-03-02
- 格式:DOCX
- 页数:15
- 大小:17.14KB
数据结构代码中缀转后缀表达式算法及源代码.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;i 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; } 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;i printf("-");} else if(k {for(i=0;i printf("-");} 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;i printf("-"); 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(); } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 代码 中缀 后缀 表达式 算法 源代码
![提示](https://static.bdocx.com/images/bang_tan.gif)