1

下面是中缀到前缀转换的代码。我的代码工作正常,直到使用reverse复制后不打印任何字符串的函数。我尝试使用for循环复制反转的字符串,但结果保持不变,程序终止而没有给出正确的输出。函数中的打印语句在reverse复制之前有效,但在复制之后无效。谁能让我知道问题出在哪里?

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

struct stack{
    int size;
    int top;
    char *arr;
};

void display(struct stack *ptr)
{
    if(ptr->top == -1)
    {
        printf("Stack is Empty");
    }
    else
    {
        for(int i = ptr->top ; i>=0 ; i--)
        {
            printf("Element: %d\n",ptr->arr[i]);
        }
    }
}

int isEmpty(struct stack *ptr)
{
    if(ptr->top == -1)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int isFull(struct stack *ptr)
{
    if(ptr->top == ptr->size - 1)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

void push(struct stack *ptr,int data)
{
    if(isFull(ptr))
    {
        printf("Stack Overflow");
    }
    else
    {
        ptr->top = ptr->top + 1;
        ptr->arr[ptr->top] = data;
    }    
}

char pop(struct stack *ptr)
{
    if(isEmpty(ptr))
    {
        printf("Stack Underflow");
        return 0;
    }
    else
    {
        char ch = ptr->arr[ptr->top];
        ptr->top = ptr->top - 1;
        return ch;
    }    
}

char stackTop(struct stack *ptr)
{
    return ptr->arr[ptr->top];
}

int isOperator(char a)
{
    if(a == '+'|| a == '-'|| a == '*'|| a == '/')
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int precedence(char a)
{
    if(a == '*' || a == '/')
    {
        return 3;
    }
    else if(a == '+' || a == '-')
    {
        return 2;
    }
    else
    {
        return -1;
    }
}

char * reverse(char exp[])
{
    int l = strlen(exp);
    int j = 0;
    char temp[l];

    for(int i=l-1;i>=0;i--,j++)
    {
        temp[j] = exp[i];
    } 
    
    
    
    temp[j] = '\0';
    printf("prefix is %s",temp);
    
    strcpy(exp,temp);
    // for(int i=0;i<=l;i++)
    // {
    //     exp[i] = temp[i];
    // }
    printf("prefix is %s",exp);
    return exp;
}

char * infix_prefix(char *infix)
{
    struct stack *sp = (struct stack *) malloc(sizeof(struct stack));

    sp->size = 100;
    sp->top = -1;
    sp->arr = (char *) malloc(sp->size * sizeof(char));
    char *prefix = (char *) malloc((strlen(infix+1)) * sizeof(char));

    
    infix = reverse(infix);
    

    int i=0; 
    int j=0;
    
    while(infix[i] != '\0')
    {
        if(infix[i] == ')')
        {
            push(sp,infix[i]);
            i++;
        }
        else if(infix[i] == '(')
        {
            while(!isEmpty(sp) && stackTop(sp) != ')')
            {
                prefix[j] = pop(sp);
                j++;
            }
            if(!isEmpty(sp))
            {
                pop(sp);
                i++;      
            } 
            else
            { 
                printf("Incorrect Expression");
                exit(0); 
            }
        }
        else if(!isOperator(infix[i]))
        {
            prefix[j] = infix[i];
            i++;
            j++;
        }
        else if(isOperator(infix[i]))
        {
            while(!isEmpty(sp) && precedence(infix[i])<=precedence(stackTop(sp)))
            {
                prefix[j] = pop(sp);
                j++; 
            }     
            push(sp,infix[i]);
            i++;   
        }
        else
        {
            printf("Incorrect expression");
            exit(0);
        }
    }

    while(!isEmpty(sp) && stackTop(sp) != '(')
    {
        prefix[j] = pop(sp);
        j++;
    }

    if(stackTop(sp) == ')')
    {
        printf("Incorrect expression");
        exit(0);
    }

    
    prefix = reverse(prefix);
    
    prefix[j] = '\0';
    
    return prefix;
}

int main(void)
{
    char *infix = "(x-y/z-k*d)";

    printf("prefix is %s",infix_prefix(infix));

    return 0;
}
4

1 回答 1

1

reverse确实有一个问题:temp数组定义的长度为:l不足以在temp[j]循环之后存储空终止符,从而导致未定义的行为。

还有更多问题:

  • char *prefix = (char *) malloc((strlen(infix+1)) * sizeof(char));没有为 的副本分配足够的空间infix。你应该写char *prefix = malloc(strlen(infix) + 1);

  • infix = reverse(infix);会崩溃,因为 to 的参数infix_prefix是一个不能修改的字符串文字。如果确实需要反转,您应该将参数声明为const char *infix并制作可修改的副本strdup(),我对此非常怀疑。

reverse这是执行反向操作的修改版本:

char *reverse(char exp[]) {
    int i = 0;
    int j = strlen(exp);

    while (j-- > i) {
        char c = exp[j];
        exp[j] = exp[i];
        exp[i++] = c;
    }
    return exp;
}
于 2021-12-11T21:55:54.413 回答