将表达式转换为后缀的程序

时间:2018-09-01 22:27:36

标签: c data-structures

我没有获得该程序的正确输出,而以abcde-* ++的形式在主程序中提供了输入

 #include<stdio.h>
 #include<stdlib.h>
 #include<string.h>

 struct Stack{
   int capacity;
   int top;
   int *array;
 };
 struct Stack* createstack(int capacity){
     struct Stack* stack=(struct Stack*)malloc(sizeof(struct Stack));
     stack->top=-1;
     stack->capacity=capacity;
     stack->array=(int*)malloc(sizeof(int)*capacity);
     return stack;
     }
 char pop(struct Stack* stack){
     return(stack->array[stack->top--]);
 }
 void push(struct Stack* stack,char ch ){

     stack->array[++stack->top]=ch;

}
 int isempty(struct Stack* stack){

    return(stack->top==-1);
}
int isfull(struct Stack* stack){
    return(stack->top==stack->capacity-1);
}
int isfront(struct Stack* stack){
    return(stack->array[stack->top]);
}




int precedence(char ch){
    switch(ch){
      case 1: ch=='+';
      case 2: ch=='-';
         return 1;
      case 3: ch=='*';
      case 4: ch=='/';
         return 2;
      case 5: ch=='^';
         return 3;

      return-1;
    }

}
int isoperand(char ch){

    return(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z');
}
void infixtopostfix(struct Stack* stack,char* exp){
       int i,k=-1;
       char res[100];
       for(i=0;exp[i];i++){
          ///if an operand is encountered
         if(isoperand(exp[i]))
            res[++k]=exp[i];
          ///if an operator is encountered
          else{
       // if(isempty(stack)||precedence(isfront(stack))<precedence(exp[i]))

        //else
            while(!isempty&&precedence(isfront(stack))>=precedence(exp[i]))
            res[++k]=pop(stack);
            push(stack,exp[i]);




         }
     }
    while(!isempty(stack))
        res[++k]=pop(stack);

        res[++k]='\0';
      printf("%s",res);

}
int main(){
struct Stack* stack=createstack(100);
char arr[100]="a+b+c*d-e";
infixtopostfix(stack,arr);
}

该程序将表达式从中缀转换为后缀 这是算法

算法 1.从左到右扫描中缀表达式。

  1. 如果扫描的字符是操作数,则将其输出。

  2. 其他,

..... 3.1如果已扫描操作符的优先级大于堆栈中操作符的优先级(或堆栈为空),则将其推入。 …..

3.2否则,从堆栈中弹出运算符,直到被扫描的运算符的优先级不等于位于堆栈顶部的运算符的优先级。将扫描的运算符推入堆栈。

  1. 重复步骤,直到扫描到中缀表达式为止。
  2. 从堆栈中弹出并输出,直到不为空。 我在我的主要功能中得到的给定输入没有得到正确的输出为abcde-*++

1 个答案:

答案 0 :(得分:1)

我不知道这些是否是您唯一的问题,但是有两点想到:

正如@rici指出的那样,您的precedence函数无法按照您认为的方式工作。正确的是:

int precedence(char ch){
    switch(ch){
      case '+':
      case '-':
         return 1;
      case '*':
      case '/':
         return 2;
      case '^':
         return 3;
      default: 
         return-1;
    }
}

检查优先级时,您具有以下条件:

while(!isempty&&precedence(isfront(stack))>=precedence(exp[i]))

这永远都行不通,因为!isempty总是评估为false。您在这里询问isempty函数的地址是否为空。不是。您真正想要做的是检查堆栈是否为空:

while(!isempty(stack) && precedence(isfront(stack))>=precedence(exp[i]))

这将调用isempty函数。

您确实应该学习使用调试器。单步执行代码将迅速揭示出我上面提到的错误。

关于堆栈实现的一些注意事项。

您在pop中有一个潜在的错误。如果有人在堆栈为空时调用它,则它可能会因为您尝试访问array[-1]而崩溃,或者它会成功访问array[-1]并返回假值。与返回错误的值相比,最好检查top的值,并引发异常(或使程序崩溃并显示一条消息)。依靠客户在致电isEmpty之前致电pop是不可靠的。

您在push中也遇到类似的错误。尝试访问超出数组范围的行为是未定义的行为。该程序可能会继续运行,并且可能会崩溃。对于push,您可能最终会推送一个随后被其他更改的值,然后pop返回您未推送的值。

由于pop中的错误,您的isEmpty函数也有一个错误。如果top的递减幅度小于-1,则isEmpty将返回false。您应该检查== -1,而不是检查< 0。即使您解决了pop问题,检查< 0还是更好。纵深防御。

不显示在栈顶的函数名称通常称为peek,而不是isfront