【问题标题】:reversed string not being returned in a c function in program of infix to prefix中缀到前缀的程序中的c函数中未返回反转字符串
【发布时间】:2022-01-16 00:12:00
【问题描述】:

下面是中缀到前缀转换的代码。我的代码工作正常,直到使用 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;
}

【问题讨论】:

  • 如果它已经编译,它是否已经编译,然后在运行时得到任何警告或错误,或者你有没有编译错误?
  • 仅供参考,这就是调试器的真正用途。我首先要意识到maininfix 指向的字符串是不可变的,但无论如何你在reverse 中都会踩到它。将char *infix 更改为char infix[] 可能会让您比现在更进一步。

标签: c string data-structures stack prefix-notation


【解决方案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); 将崩溃,因为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;
}

【讨论】:

  • 感谢您的回答,我更改了每个数组的内存分配方法,并为其指定了足够大的特定大小以供程序运行,现在程序运行正常。
猜你喜欢
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-13
相关资源
最近更新 更多