前中后缀表达式计算 无误c语言.docx

上传人:b****5 文档编号:29625517 上传时间:2023-07-25 格式:DOCX 页数:20 大小:19.45KB
下载 相关 举报
前中后缀表达式计算 无误c语言.docx_第1页
第1页 / 共20页
前中后缀表达式计算 无误c语言.docx_第2页
第2页 / 共20页
前中后缀表达式计算 无误c语言.docx_第3页
第3页 / 共20页
前中后缀表达式计算 无误c语言.docx_第4页
第4页 / 共20页
前中后缀表达式计算 无误c语言.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

前中后缀表达式计算 无误c语言.docx

《前中后缀表达式计算 无误c语言.docx》由会员分享,可在线阅读,更多相关《前中后缀表达式计算 无误c语言.docx(20页珍藏版)》请在冰豆网上搜索。

前中后缀表达式计算 无误c语言.docx

前中后缀表达式计算无误c语言

#include/*导入需要用到的各种包*/

#include

#include

typedefstruct/*定义结构体用来存储操作符*/

{

charop;/*存储字符*/

intlevel;/*存储优先级*/

}OpNode;

typedefstruct

{

OpNodeop[100];

inttop;

intsize;/*表示栈内元素的个数*/

}stack;/*定义符号栈*/

voidinit(stack*st)/*初始化栈*/

{

st->size=0;

st->top=0;

}

OpNodepop(stack*a)

{

if(a->size==0)/*如果栈为空结束操作*/

{

exit(-1);

}

a->size--;

returna->op[--(a->top)];/*取出栈顶元素*/

}

voidpush(stack*a,OpNodeop)/*入栈函数*/

{

a->size++;

a->op[(a->top)++]=op;

}

OpNodetop(stack*a)/*观察栈顶函数*/

{

if(a->size==0)/*如果栈为空结束操作*/

{

printf("stackisempty\n");

exit(-1);

}

returna->op[(a->top)-1];/*只得到栈顶的值而不出栈*/

}

typedefstruct/*定义数值栈*/

{

doublenum[100];

inttop;/*栈顶指针*/

intsize;

}numstack;

voidinit2(numstack*st)/*初始化数值栈*/

{

st->size=0;

st->top=0;

}

doublepop2(numstack*a)/*数值栈出栈*/

{

if(a->size==0)/*出栈前的判空*/

{

exit(-1);

}

a->size--;

returna->num[--(a->top)];/*得到栈顶的值*/

}

voidpush2(numstack*a,doublenum)/*入栈*/

{

a->size++;

a->num[(a->top)++]=num;

}

intmain(void)/*主函数*/

{

voidchange(charstr[],charexp[]);/*声明要用到的各个函数*/

doubleCalResult(charexp[]);/*声明后缀表达式的计算函数*/

doubleDirectcalresult(charstr[]);

intcheck(charstr[],charchestr[100]);

charstr[100],exp[100],chestr[100];/*str存储原算术表达式,exp存储对应的printf("算术表达式为:

\n");后缀表达式,chestr存储容错字符'^'*/

gets(str);

if(check(str,chestr))/*调用容错函数*/

{printf("表达式错在:

\n");

printf("%s\n",str);

printf(chestr);/*根据输入情况指出错误的地方*/

exit(-1);

}

change(str,exp);/*调用函数将中缀转化为后缀*/

printf("后缀表达式为:

%s\n",exp);

printf("运算结果为:

%f\n",CalResult(exp));/*调用函数计算后缀表达式*/

printf("直接运算的结果为:

%f\n",Directcalresult(str));/*调用直接计算函数*/

}

voidchange(charstr[],charch[])/*将前缀表达式转化为后缀表达式*/

{

inti=0;/*str的索引*/

intk=0;

charc;/*字符串中取出的放在C中*/

stackst;/*定义符号栈*/

OpNodeop;

OpNodeops;

init(&st);/*初始化符号栈*/

c=str[i++];

while(c!

='\0')/*对字符串进行扫描*/

{

if((c>='0'&&c<='9')||c=='.')/*如果字符为数字或小数点*/

{

while((c>='0'&&c<='9')||c=='.')

{

ch[k++]=c;/*将字符直接放入数组中*/

c=str[i++];

}

ch[k++]='|';/*在其后面放入一个分隔符*/

}

if(c=='(')/*如果字符是左括号*/

{

op.op='(';

op.level=-1;/*定义其优先级为-1*/

push(&st,op);/*将左括号直接入栈*/

}

if(c==')')/*如果字符为右括号*/

{

op=top(&st);/*首先观察栈顶*/

while(st.size!

=0&&op.op!

='(')/*如果不是左括号并且栈不为空*/

{

op=pop(&st);/*出栈并存入数组中*/

ch[k++]=op.op;

if(st.size>0)/*再次检查栈是否为空,*/

op=top(&st);

elsebreak;/*为空就结束*/

}

pop(&st);/*去掉左括号*/

}

if(c=='+'||c=='-')/*如果是+-号*/

{

op.op=c;

op.level=1;/*优先级为1*/

if(st.size==0)

{

push(&st,op);/*如果此时栈为空直接入栈*/

}

else

{

ops=top(&st);/*观察栈顶*/

while(ops.level>=op.level)/*如果栈顶优先级高*/

{

ops=pop(&st);

ch[k++]=ops.op;/*将栈顶元素取出存入数组中*/

if(st.size>0)

ops=top(&st);/*进行判空操作,栈为空结束*/

else

break;

}

push(&st,op);/*此时栈顶优先级低,入栈*/

}

}

if(c=='*'||c=='/'||c=='%')

{

op.op=c;

op.level=2;/*优先级为1*/

if(st.size==0)

{

push(&st,op);/*如果此时栈为空直接入栈*/

}

else

{

ops=top(&st);/*观察栈顶*/

while(ops.level>=op.level)/*如果栈顶优先级高*/

{

ops=pop(&st);/*将栈顶元素取出存入数组中*/

ch[k++]=ops.op;

if(st.size>0)

ops=top(&st);/*进行判空操作,栈为空结束*/

else

break;

}

push(&st,op);/*此时栈顶优先级低,入栈*/

}

}

c=str[i++];/*索引自加检索下一个字符*/

}

while(st.size!

=0)/*最后判断栈如果不为空*/

{

ops=pop(&st);/*取出栈内元素存入数组中*/

ch[k++]=ops.op;

}

ch[k]='\0';/*将\0作为结尾存入数组*/

}

doubleCalResult(charexp[])/*后缀表达式的计算*/

{

charc;

numstacknumst;/*建立数值栈*/

doubled1,d2,dr;

intk=0;/*后缀表达式的索引*/

inti=0;/*将字符转化为浮点数的索引*/

char*s;

chartrans[100];/*存字符表示的一段数字*/

init2(&numst);/*实现数值栈*/

c=exp[k++];

while(c!

='\0')/*开始扫描后缀表达式*/

{

if(c=='+'||c=='-'||c=='*'||c=='/'||c=='%')/*如果是操作符*/

{

switch(c)

{

case'+':

/*如果是加法操作*/

d2=pop2(&numst);

d1=pop2(&numst);

dr=d1+d2;/*相加后入栈*/

push2(&numst,dr);

break;

case'-':

/*如果是减法操作*/

d2=pop2(&numst);

d1=pop2(&numst);

dr=d1-d2;/*相减后入栈*/

push2(&numst,dr);

break;

case'*':

/*如果是乘法操作*/

d2=pop2(&numst);

d1=pop2(&numst);

dr=d1*d2;/*相乘后入栈*/

push2(&numst,dr);

break;

case'/':

/*如果是除法操作*/

d2=pop2(&numst);

d1=pop2(&numst);

dr=d1/d2;/*相除后入栈*/

push2(&numst,dr);

break;

case'%':

/*如果是取余操作*/

d2=pop2(&numst);

d1=pop2(&numst);

dr=(double)((int)d1%(int)d2);/*类型转化并取余后入栈*/

push2(&numst,dr);

break;

}

}

if(c>='0'&&c<='9'||c=='.')/*如果是字符表示的数字*/

{

while(c>='0'&&c<='9'||c=='.')

{

trans[i++]=c;/*将字符存入数组进行下一个的扫描*/

c=exp[k++];

}

trans[i++]='\0';/*将表示数字的字符串结束*/

i=0;

s=trans;/*将指针指向该数组*/

d1=atof(s);/*利用函数将字符串转化为浮点数*/

push2(&numst,d1);

}

c=exp[k++];

}

returnpop2(&numst);/*最后结果将在数值栈中,取出作为返回值*/

}

doubleDirectcalresult(charstr[])/*表达式的直接计算出结果*/

{

stackms;/*建立符号栈*/

numstackmns;/*建立数值栈*/

doublecalculate(doubleod1,doubleod2,OpNodeop);

intindex=0;/*str的索引*/

intlen=strlen(str);

charc;

chartrans[100];/*存放数值的一段字符*/

inti=0;/*trans的索引*/

char*s;

doubled;

OpNodetempn;/*存放当前扫描的操作符*/

OpNodetempln;

doubleoda,odb,odr;

doubleresult;/*作为返回值返回结果*/

init(&ms);/*实现两个栈*/

init2(&mns);

while(index

{

c=str[index++];

if(c>='0'&&c<='9'||c=='.')/*如果是数字字符或小数点*/

{

while(c>='0'&&c<='9'||c=='.')

{

trans[i++]=c;/*将其存入数组扫描下一个*/

c=str[index++];

}

trans[i++]='\0';/*扫描完一个数结束数组*/

i=0;/*索引归0*/

s=trans;

d=atof(s);

push2(&mns,d);/*转化为浮点数入栈*/

}

if(c=='+'||c=='-')/*如果是+-*/

{

tempn.level=1;/*优先级设为1*/

tempn.op=c;

if(ms.size==0)

{

push(&ms,tempn);/*栈为空直接入栈*/

}

else

{

templn=top(&ms);

while(templn.level>=tempn.level)/*栈顶优先级高*/

{

templn=pop(&ms);/*取出操作数和操作符计算*/odb=pop2(&mns);

oda=pop2(&mns);

odr=calculate(oda,odb,templn);

push2(&mns,odr);/*结算结果入栈*/

if(ms.size>0)

{

templn=top(&ms);/*如果栈空结束*/

}

else

break;

}

push(&ms,tempn);/*操作符入栈*/

}

}

if(c=='*'||c=='/'||c=='%')

{

tempn.level=2;/*定义优先级为2*/

tempn.op=c;

if(ms.size==0)

{

push(&ms,tempn);/*栈空直接入栈*/

}

else

{

templn=top(&ms);

while(templn.level>=tempn.level)/*栈顶优先级高*/

{

templn=pop(&ms);/*取出操作数和操作符计算*/

odb=pop2(&mns);

oda=pop2(&mns);

odr=calculate(oda,odb,templn);

push2(&mns,odr);/*结算结果入栈*/

if(ms.size>0)

{

templn=top(&ms);

}

else

break;/*如果栈空结束*/

templn=top(&ms);

}

push(&ms,tempn);/*操作符入栈*/

}

}

if(c=='(')/*如果是左括号*/

{

tempn.level=-1;

tempn.op=c;/*直接入栈优先级定位-1*/

push(&ms,tempn);

}

if(c==')')/*如果是右括号*/

{

while(tempn.op!

='(')/*遇到左括号结束*/

{

templn=pop(&ms);

odb=pop2(&mns);/*从数栈中取两个数,从符号栈里取操作符*/

oda=pop2(&mns);

odr=calculate(oda,odb,templn);/*计算出结果入栈*/

push2(&mns,odr);

if(ms.size>0)

tempn=top(&ms);

else

break;/*如果栈空结束*/

}

pop(&ms);/*取出左括号*/

}

}

tempn=top(&ms);

while

(1)

{

templn=pop(&ms);

odb=pop2(&mns);/*从数栈中取两个数,从符号栈里取操作符*/

oda=pop2(&mns);

odr=calculate(oda,odb,templn);/*计算出结果入栈*/

push2(&mns,odr);

if(ms.size>0)

tempn=top(&ms);/*如果栈空结束*/

else

break;

}

result=pop2(&mns);/*最后的结果在数值栈中返回*/

returnresult;

}

doublecalculate(doubleod1,doubleod2,OpNodeop)/*已知操作符和操作数的计算*/

{

switch(op.op)

{

case'+':

returnod1+od2;

case'-':

returnod1-od2;/*判断操作符是哪个执行相应计算*/

case'*':

returnod1*od2;

case'/':

returnod1/od2;

case'%':

return(double)((int)od1%(int)od2);

}

return0;/*如果上面的都没有执行返回0*/

}

intcheck(charstr[],charchestr[100])/*容错函数*/

{

charc;

charcdivide;

inti=0;/*str的索引*/

stackche;/*括号匹配用到的栈*/

OpNodetemp;

intk=0;/*chestr的索引*/

intisinteger(charinteger[100]);/*%计算是判断是否是整数*/

chars1[10];/*%操作时存储%左右的数字*/

chars2[10];

intindexs1=0;/*s1s2的索引*/

intindexs2=0;

init(&che);

intflag=0;/*0——没有出错1——有错*/

inttag=0;

c=str[i];/*开始扫描*/

intj;/*数组chestr索引*/

for(j=0;j<99;j++)

{

chestr[j]='';/*数组初始化待以后加入'^'*/

}

chestr[j]='\0';

while(c!

='\0')

{

if(c=='(')/*如果是左括号就入栈*/

{

temp.op=c;

push(&che,temp);

}

if(c==')')/*如果是右括号*/

{

if(che.size>0)

{

pop(&che);/*栈不为空就取出一个左括号*/

}

else

{

flag=1;

printf("缺少左括号\n");/*否则提示有错*/

chestr[i]='^';/*右括号下加'^'*/

}

}

if(c=='/')/*判断除数是否为0*/

{

j=0;

cdivide=str[i+1+j];/*取出除号后的数*/

while(cdivide>='0'&&cdivide<='9'||cdivide=='.')/*如果是数或小数点就一直存*/

{

s1[j++]=cdivide;

if(cdivide!

='0'&&cdivide!

='.')/*如果不是0则正确并结束*/

{

tag=1;

break;

}

cdivide=str[i+j+1];

}

if(!

tag)/*如果tag为0则存在错误除数为0*/

{

chestr[i+1]='^';

flag=1;/*flag为1表示有错*/

}

}

if(c=='%')/*取余操作的容错*/

{

while(str[i-indexs1-1]>='0'&&str[i-indexs1-1]<='9'

||str[i-indexs1-1]=='.')/*以%为中心向前扫描*/

{

s1[indexs1++]=str[i-indexs1-1];/*如果是数或小数点*/

}/*放在s1中*/

while(str[i+indexs2+1]>='0'&&str[i+indexs2+1]<='9'/*以%为中心向后扫描*/

||str[i+indexs2+1]=='.')

{/*如果是数或小数点*/

s2[indexs2++]=str[i+indexs2+1];/*放在s1中*/

}

if(isinteger(s1))/*调用函数判断s1内存到是否是整数*/

{

printf("取余算法第一个数应为整数运算\n");

flag=1;/*记录为有错*/

chestr[i-indexs1]='^';

}

if(isinte

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1