【问题标题】:Logical error in recursive function递归函数中的逻辑错误
【发布时间】:2015-06-01 06:50:09
【问题描述】:

我正在编写一个程序来使用递归检查字符串是否为回文。回文字符串可以向后读取,就像向前读取一样。但是以下是我的代码:

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

int main()
{
int num;
printf("Enter the number of characters in your string\n");
scanf("%d",&num);
char string[num];
char string2[num];
int i;
printf("Enter your string\n");
for (i=0;i<num;i++)
{
    scanf("%c",&string[i]);
}
fillString(string,string2,num);
int palin = isPalind(string,string2,num);
if (palin) printf("The string you entered is palindrome");
else printf("The string you entered is not palindrome");

return 0;
}

int isPalind(char string[],char string2[],int num)
{
int i=0;
while (i<num)
{
    if (string[i]!=string2[i])
    {
        i++;
        return 0;

    }
    else{

        i++;
        return 1*isPalind(string,string2,num);

    }
}

}

void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<num;i++)
    string2[i-1]=string[num-i];

}

我有一个逻辑错误,程序编译正常并执行,但它总是给出“字符串不是回文”

【问题讨论】:

  • 你为什么打电话给return 1*isPalind(string,string2,num);
  • 首先我输入字符串中的字符数,然后输入字符串,但无论我的字符串是什么,它总是会给我“字符串不是回文”
  • @Wimmel 这是递归,所以它会一直执行直到计数器等于数字或直到它发现字符串不是回文(从结果“0”)
  • @RayaRateb 但在每个递归调用中,您将 i 设置回 0,并且只比较第一个字符。
  • @RayaRateb 顺便说一句,问题可能是你的scanf,见Why scanf(“%d”, …) does not consume '\n'?

标签: c string recursion


【解决方案1】:

fillString 中,循环迭代num-1 次(i 是从1num-1),因此不会复制整个字符串。原始字符串的第一个字符被省略。你应该这样做

for (i=1;i<=num;i++) ...

至于递归函数,它并不是真正的递归。在递归调用中应该传递 modified 输入,但在您的情况下,传递的是完全相同的输入。因此,在真正回文的情况下,您很可能会由于未终止而导致堆栈溢出。我会提出另一种方法,以递归方式处理单个字符串:
1) 基本情况:如果长度为 0 或 1,则字符串是回文
2)递归步骤:如果第一个字符等于最后一个并且字符串没有第一个和最后一个字符是回文,则字符串是回文。

【讨论】:

    【解决方案2】:

    您的 fillString() 函数是否按预期反转了您的字符串?看起来 string1 的第一个字母没有被添加到 string2 的最后一个位置,因为当 i

    仔细检查这个例子:

    给定:String1 =“你好”。 String2 = null 现在。数量 = 5。

    void fillString(char string[],char string2[],int num)
    {
    int i;
    for (i=1;i<num;i++)
        string2[i-1]=string[num-i];
    
    }
    

    当 i = 4 时,你有 string2 = 'olle'。当 i = 5 时,for 循环条件失败,因此不会填充 string2[4] = 'H'。

    更新:

    void fillString(char string[],char string2[],int num)
    {
    int i;
    for (i=1;i<=num;i++)
        string2[i-1]=string[num-i];
    
    }
    

    【讨论】:

      【解决方案3】:

      这两个函数都是错误的。它们可以这样写

      int isPalind( const char string[], const char string2[], int num )
      {
          return ( num == 0 ) || 
                 ( string[0] == string[--num] && isPalind( string + 1, string2, num ) ); 
      
      }
      
      void fillString( const char string[], char string2[], int num )
      {
          int i;
          for ( i = 0; i < num; i++ ) string2[i] = string[num-i-1];
      }
      

      如果您不需要递归函数,那么您可以简单地使用标准函数memcmp 来确定两个字符串是否相等。

      【讨论】:

      • @Eugene Sh.正是 memcpy,因为他的字符数组不包含字符串。
      • @Eugene Sh.我的意思是memcmp。这是一个错字。
      猜你喜欢
      • 1970-01-01
      • 2013-01-10
      • 2021-07-20
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      相关资源
      最近更新 更多