当前位置: 首页 > 知识库问答 >
问题:

c语言,中缀式转后缀式前缀式然后求值,无法入栈?

涂泰平
2024-02-29

我写了一个中缀式转化为后缀式,前缀式,并计算出中前后缀式结果的代码,但是在确保输入格式正确后(我输入的是: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函数中的逻辑错误,导致该弹栈的时候把栈提前清空了,等再弹栈的时候没有元素了,把逻辑理清了就解决了。

共有1个答案

章宏恺
2024-02-29
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 因此我们需要将左括号转换为右括号,反