中缀到前缀的程序中的c函数中未返回反转字符串

Posted

技术标签:

【中文标题】中缀到前缀的程序中的c函数中未返回反转字符串【英文标题】:reversed string not being returned in a c function in program of infix to prefix 【发布时间】: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[] 可能会让您比现在更进一步。 【参考方案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;

【讨论】:

感谢您的回答,我更改了每个数组的内存分配方法,并为其指定了足够大的特定大小以供程序运行,现在程序运行正常。

以上是关于中缀到前缀的程序中的c函数中未返回反转字符串的主要内容,如果未能解决你的问题,请参考以下文章

Python中的中缀到前缀转换

LeetCode 2000 反转单词前缀[字符串] HERODING的LeetCode之路

在中缀表达式中反转运算符优先级

C语言试题二十六之请编写一个函数function(char *s),该函数的功反转字符串中的内容。

C语言试题二十六之请编写一个函数function(char *s),该函数的功反转字符串中的内容。

如何在程序中将中缀表达式转换为后缀表达式