我写了一个中缀式转化为后缀式,前缀式,并计算出中前后缀式结果的代码,但是在确保输入格式正确后(我输入的是:11+22*(9-6)/3#),输出为:Have no target!!,我想了好久,觉得是输入的式子没有办法入栈,但是找不出来哪里有问题,能帮我看一下是哪里的问题吗?谢谢各位大佬!
以下是我的代码:
#include<stdio.h>#include<stdlib.h>#include<malloc.h>#define STACKSIZE 100#define SIZECRIMENT 10typedef struct { float *top; float *base; int stacksize;}Sqstack1;typedef struct { char *top; char *base; int stacksize;}Sqstack2;void initstack1(Sqstack1 *s){ s->base=(float*)malloc(STACKSIZE*sizeof(float)); if(!s->base){ printf("Don't have enough space!\n");exit(1);} s->top=s->base; s->stacksize=STACKSIZE;} void initstack2(Sqstack2 *s){ s->base=(char*)malloc(STACKSIZE*sizeof(char)); if(!s->base){printf("Don't have enough space!\n");exit(1); } s->top=s->base; s->stacksize=STACKSIZE;} void GetTop1(Sqstack1 *s,float *e){ if(s->top==s->base){ printf("Have no target!\n");exit(1); } *e=*(s->top-1);} void GetTop2(Sqstack2 *s,char *e){ if(s->top==s->base){printf("Have no target!!\n");exit(1); } *e=*(s->top-1);} void Push1(Sqstack1 *s,float e){ if((s->top-s->base)>=s->stacksize){ printf("The Sqstack1 is full,we are finding more continuous space!\n"); s->base=(float*)realloc(s->base,(STACKSIZE+SIZECRIMENT)*sizeof(float)); if(!s->base){ printf("Don't have more continuous space!\n");exit(1);} s->top=s->base+s->stacksize; s->stacksize+=SIZECRIMENT;} *s->top=e;s->top++;}void Push2(Sqstack2 *s,char e){ if((s->top-s->base)>=s->stacksize){ printf("The Sqstack2 is full,we are finding more continuous space!\n"); s->base=(char*)realloc(s->base,(STACKSIZE+SIZECRIMENT)*sizeof(char)); if(!s->base){ printf("Don't have enough continuous space!\n");exit(1);} s->top=s->base+s->stacksize; s->stacksize+=SIZECRIMENT;} *s->top=e;s->top++;}void Pop1(Sqstack1 *s,float *e){ if(s->top==s->base){ printf("the Sqstack1 is empty!\n");exit(1); } *e=*--s->top;}void Pop2(Sqstack2 *s,char *e){ if(s->top==s->base){ printf("The Sqstack2 is empty!\n");exit(1); } *e=*--s->top;}int priority(char s1,char s2){ char chars[2]; int prioritys[2]; int i; chars[0]=s1; chars[1]=s2; for(i=0;i<2;i++){ switch(chars[i]){ case'*': case'/': case'%':prioritys[i]=2;break; case'+': case'-':prioritys[i]=1;break; case'(': case')': case'#':prioritys[i]=0;break; } } if(prioritys[0]>=prioritys[1]) return 1;else return 0;}void suffix(char *s){ Sqstack2 S; initstack2(&S); //s是中缀表达式数组,s1是后缀表达式数组,S用于操作栈; char s1[100];char e; int i=0,j=0; Push2(&S,'$'); while(s[i]!='#'){ if((s[i]<='9')&&(s[i]>='0')){ s1[j++]=s[i];} else switch(s[i]){ case'(':Push2(&S,s[i]);break; case')':GetTop2(&S,&e);while(e!='('){ s1[j++]=e; Pop2(&S,&e);}break; default:while(GetTop2(&S,&e),priority(e,s[i])){//当操作栈不为空且中缀式指针运算符 //优先级大于操作栈顶元素时; Pop2(&S,&e);//此时e指针内容为 操作栈顶元素;出操作栈; s1[j++]=e;} //出操作栈的运算符写入后缀式; Push2(&S,s[i]);}//找到比s[i]优先级小的运算符或者操作栈空时,将s[i]放入S操作栈; i++; }while(GetTop2(&S,&e),e!='$'){ Pop2(&S,&e);s1[j++]=e; } s1[j]='\0'; printf("The suffix expression is:\n"); puts(s1);}void reversal(char *s){ Sqstack2 S;char e; initstack2(&S); char s1[100]; int i=0,j=0; Push2(&S,'a'); Push2(&S,'#'); while(s[i]!='#'){ Push2(&S,s[i]); i++; } while(GetTop2(&S,&e),e!='a'){ Pop2(&S,&e);s1[j++]=e; } s[j]='\0'; for(i=0;i<j;i++){ s[i]=s1[i]; }}void prefix(char *s){ char s1[100]; Sqstack2 S; initstack2(&S); reversal(s); char e; int i=0,j=0; Push2(&S,'$'); while(s[i]!='#'){ if((s[i]<='9')&&(s[i]>='0')){ s1[j++]=s[i];i++; } else switch(s[i]){ case ')':Push2(&S,')');i++;break; case '(':while(GetTop2(&S,&e),e!=')'){//e内容为S栈顶元素; Pop2(&S,&e);s1[j++]=e; }Pop2(&S,&e);break;//e内容为‘)’; default:while(GetTop2(&S,&e),priority(e,s[i])){//此时*e为S操作栈 //栈顶元素; Pop2(&S,&e);s1[j++]=e;} //此时*e为S操作栈栈顶元素; Push2(&S,s[i]);i++; } } while(GetTop2(&S,&e),e!='$'){ Pop2(&S,&e);s1[j++]=e; } reversal(s1); s1[j]='\0'; printf("The prefix expression is:\n"); puts(s1);}void calculate_prefix(Sqstack1 *S,char *s){ reversal(s); initstack1(S); float e;int i=0; float x,y,z,m; while(s[i]!='#'){ if((s[i]>='0')&&(s[i]<='9')){ m=s[i]-'0'; Push1(S,m);i++; } else { Pop1(S,&x); Pop1(S,&y); switch(s[i]){ case '+':z=x+y;break; case '-':z=y-x;break; case '*':z=x*y;break; case '/':z=y/x;break; case '%':z=(int)y%(int)x;break; } Push1(S,z);i++;} } GetTop1(S,&e); printf("The prefix_expression's result is:%.2f",e);}void calculate_suffix(Sqstack1 *S,char *s){ initstack1(S); float e;int i=0; float x,y,z,m; while(s[i]!='#'){ if((s[i]>='0')&&(s[i]<='9')){ m=s[i]-'0'; Push1(S,m);i++; } else { Pop1(S,&x);Pop1(S,&y); switch(s[i]){ case '+':z=x+y;break; case '-':z=y-x;break; case '*':z=x*y;break; case '/':z=y/x;break; case '%':z=(int)y%(int)x;break; } Push1(S,z);i++;} } GetTop1(S,&e); printf("The suffix_expression's result is:%.2f",e);}void calculate_infix(Sqstack2 *S,char *s){ Sqstack1 S1; initstack2(S); //s是中缀表达式数组,s1是后缀表达式数组,S用于操作栈; char s1[100];char e;char k='$'; int i=0;int j=0; Push2(S,k); while(s[i]!='#'){ if((s[i]<='9')&&(s[i]>='0')) s1[j++]=s[i]; else switch(s[i]){ case'(':Push2(S,s[i]);break; case')':Pop2(S,&e);while(e!='('){ s1[j++]=e; Pop2(S,&e);}break; default:GetTop2(S,&e);//此时的e指针内容为 操作栈顶元素; while(GetTop2(S,&e),priority(e,s[i])){//当操作栈不为空且中缀式指针运算符 //优先级大于操作栈顶元素时; Pop2(S,&e);//此时e指针内容为 操作栈顶元素;出操作栈; s1[j++]=e;} //出操作栈的运算符写入后缀式; Push2(S,s[i]);}break;//找到比s[i]优先级小的运算符或者操作栈空时,将s[i]放入S操作栈; i++; }while(GetTop2(S,&e),e!='$'){ Pop2(S,&e);s1[j++]=e; } calculate_suffix(&S1,s1);}int main(){ Sqstack1 S1; Sqstack2 S; char s[100]; printf("Please input the infix expression!"); fgets(s,100,stdin); puts(s); suffix(s); prefix(s); calculate_infix(&S,s); printf("Please input the suffix expression!"); fgets(s,100,stdin); calculate_suffix(&S1,s); printf("Please input the prefix expression!"); fgets(s,100,stdin); calculate_prefix(&S1,s); return 0;}
主函数中将
suffix(s);prefix(s);alculate_infix(&S,s);
改为
calculate_infix(&S,s); suffix(s);prefix(s);
输出变成了“The Sqstack2 is empty!”
试过修改initstack1(*S);为Stack1 S; initstack1(&S);输出从原来什么也没有变成了上述问题;
查了谷歌,谷歌说puts函数不稳定,试过把原来的puts函数改为fputs函数,但是问题没有解决;
试过把Pop,Push函数里参数,加删*,加删&,并调整整体相关部分运行代码,但是还是上述问题,所以我觉得是我输入的式子压根没有入栈;
希望能输出后缀式和前缀式,并输出计算结果。
////我在switch语句中加了case:‘$’:priority[i]=0;break;现在后缀表达式输出了,但是前缀表达式依旧是老问题
////谢谢,原来是我Pop,Push函数中的逻辑错误,导致该弹栈的时候把栈提前清空了,等再弹栈的时候没有元素了,把逻辑理清了就解决了。
void suffix(char *s) {... default:while(GetTop2(&S,&e),priority(e,s[i])){//当操作栈不为空且中缀式指针运算符 //优先级大于操作栈顶元素时; Pop2(&S,&e);//此时e指针内容为 操作栈顶元素;出操作栈; s1[j++]=e;} //出操作栈的运算符写入后缀式; Push2(&S,s[i]);}//找到比s[i]优先级小的运算符或者操作栈空时,将s[i]放入S操作栈;}
GetTop2(&S,&e)
得到的不一定是一个操作符啊。
当操作栈不为空且中缀式指针运算符优先级大于操作栈顶元素时;
这个注释写的和代码表述的矛盾啊?应该是操作栈顶元素优先级大于中缀式指针运算符吧
。还有一种情况没有考虑,当优先级相等且为左结合的时候,也要Pop出来。
当你编写一个算术表达式如 B*C 时,表达式的形式使你能够正确理解它。在这种情况下,你知道 B 乘以 C, 因为乘法运算符 * 出现在表达式中。这种类型的符号称为中缀,因为运算符在它处理的两个操作数之间。看另外一个中缀示例,A+B*C,运算符 + 和 * 仍然出现在操作数之间。这里面有个问题是,他们分别作用于哪个运算数上,+ 作用于 A 和 B , 还是 * 作用于 B 和 C?表达式似乎有点模糊
本文向大家介绍中缀表达式转后缀表达式相关面试题,主要包含被问及中缀表达式转后缀表达式时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 对于中缀表达式,遇到操作数直接将其输出,如果遇到操作符和左括号全部压入栈中,若遇到右括号则将栈中元素全部弹出,直到遇到左括号为止。压栈过程中,若遇到其它操作符,从栈中弹出元素直到遇到更低优先级的操作符为止。
本文向大家介绍将中缀转换为后缀表达式,包括了将中缀转换为后缀表达式的使用技巧和注意事项,需要的朋友参考一下 前缀表达式是人类可读和可解的。我们可以轻松地区分算子的顺序,也可以在计算数学表达式时先使用括号将其求解。计算机无法轻松地区分运算符和括号,这就是为什么需要后缀转换的原因。 要将中缀表达式转换为后缀表达式,我们将使用堆栈数据结构。通过从左到右扫描infix表达式,当我们得到任何操作数时,只需将
题3-3 后缀式计算 题目描述 输入一个后缀表达式,试计算该表达式的结果。 规定:后缀表达式的长度不超过一行(80个字符),以$作为输入结束,操作数、操作符之间用空格分隔,操作符只可能有+、-、*、/四种运算,操作数均为整数且运算过程不超出int型范围。例如:234 34 + 2 * $。 输入格式: 测试数据有多组,处理到文件尾。每组测试数据在一行上输入不超过80个字符的合法的后缀表达式,数据之
我的讲师给了我一个任务,让我创建一个程序,使用堆栈将表达式和中缀转换为后缀。我制作了堆栈类和一些函数来读取中缀表达式。 但是这个函数,叫做,它负责使用堆栈将数组inFix中的inFix表达式转换为数组postFix中的postfix表达式,并没有做它应该做的事情...你们能帮帮我告诉我哪里做错了吗? 下面是从中缀转换为后缀的函数的代码,是我需要帮助修复的代码: 注意:convertToPostfi
本文向大家介绍将中缀转换为前缀表达式,包括了将中缀转换为前缀表达式的使用技巧和注意事项,需要的朋友参考一下 要通过计算机求解表达式,我们可以将其转换为后缀形式或前缀形式。在这里,我们将看到中缀表达式如何转换为前缀形式。 首先,中缀表达式反转。注意,对于反转,圆括号也将反转。 例如:表达式:A + B *(C-D) 反转后的表达式为:)D – C(* B + A 因此我们需要将左括号转换为右括号,反