【问题标题】:C Program to Check for Palindrome String用于检查回文字符串的 C 程序
【发布时间】:2021-09-15 10:36:54
【问题描述】:

我编写了两个示例程序来检查回文字符串。但在两者中,我都得到了输出,它不是回文数。我错过了什么?

我严格假设代码以某种方式执行我的 if 语句并将标志放入 1。可能是因为该长度计算。谁有更好的主意?

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    
    int main(void) {
        setbuf(stdout,NULL);
        char name[100];
        int i,length,flag=0,k;
        printf("Enter your name");
        /*scanf("%s",name);*/
        gets(name);
        length=strlen(name);
        for(i=0;i<=length-1;i++)
        {
            for(k=length-1;k>=0;k--)
            {
                if(name[i]!=name[k])
                {
                    flag=1;
                    break;
    
                }
    
                }
            }
    
        if(flag==0)
        {
            printf("Give word is a palindrome");
        }
        if(flag==1)
        {
            printf("This is NOT a palindrome word");
        }
        return 0;
        }

和

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

int main(void) {
    setbuf(stdout,NULL);
    char name[100];
    int i,length,flag=0;
    printf("Enter your name");
    /*scanf("%s",name);*/
    gets(name);
    length=strlen(name);
    for(i=0;i<=length/2;i++)
    {
        if(name[i]!=name[length-1])
        {
            flag=1;
        }
    }


    if(flag==0)
    {
        printf("Give word is a palindrome");
    }
    if(flag==1)
    {
        printf("This is NOT a palindrome word");
    }
    return 0;
    }

【问题讨论】:

  • 在第二个sn-p中,声明if (name[i] != name[length - 1]),我猜你想要if (name[i] != name[length - i - 1])
  • 在第一个代码中,您将每个字母与每个字母进行比较;在第二个代码中,您始终与最后一个字母进行比较
  • 阅读this。
  • OT: for(i=0;i&lt;=length-1;i++) --> for(i=0;i&lt;length-1;i++)
  • 您是否偶然在搜索框中搜索了"[c] palindrome"?有几十个,如果不是数百个答案。也许Answer - How to remove spaces and check if a string is a palindrome?

标签: c algorithm palindrome


【解决方案1】:

试试这个

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

    #include <string.h>
    int main() {
       char text[100];
       int begin, middle, end, length = 0;
       printf("enter the name: ");
       scanf("%s",text);
       while ( text[length] != '\0' ){
            length++;}

       end = length - 1;
       middle = length/2;
       for ( begin = 0 ; begin < middle ; begin++ ) {
           if ( text[begin] != text[end] ) {
              printf("Not a palindrome.\n");
              break;
           }
           end--;
         }
         if( begin == middle )
              printf("Palindrome.\n");
              return 0;
     }

第一段代码的问题是你在比较它超出了要求,将它与length-i-1比较。

第二个代码的主要问题是您只将它与单词的最后一个字母进行比较。

希望你理解你的错误

【讨论】:

  • 只是提醒scanf("%s",text); 并不比gets() 更安全,请参阅Why gets() is so dangerous it should never be used!。总是,总是 使用字段宽度修饰符来显式防止读取超出数组末尾并调用 Undefined Behavior(并防止缓冲区利用)。例如。 if (scanf("%99s",text) != 1) return 1; 另外,如果用户单独输入"I",您的代码会发生什么情况? (提示:begin = middle = 0; 和 end = 1)
  • 是的,感谢您提供的信息,但由于这是一个简单的程序,我没有过多考虑安全性,下次我会在实施时牢记这一点。
  • 当然,不叮,很高兴帮助指出“改进机会”:)
  • 我的解决方案是否还有其他错误
  • 您在if( begin == middle ) 上的缩进有点误导,因为它没有受到{ .. } 的保护,而return 0; 不是if 的一部分(应该很清楚)。除此之外,它似乎运作良好。其他想法是使用fgets (text, sizeof text, stdin),然后使用text[strcspn (text, "\n")] = 0; 从末尾删除'\n'。这样你就可以处理"A man a plan a canal Panama"你已经包含string.h所以将while ( text[length] != '\0' )更改为length = strlen (text);
【解决方案2】:

你的两次尝试都有很多错误。我强烈建议使用调试器来调查您的代码如何工作(或不工作)。

您的第一次尝试执行length2(不正确)比较,而显然只需要length / 2 比较。第二个执行length / 2比较但比较不正确:

name[i] != name[length-1] ;

应该是:

name[i] != name[length - i - 1] ;

最后,当您知道它们不是回文时(在第一次不匹配时)可以终止比较时,您最终会进行详尽的迭代。

可能还有其他错误——老实说,我并没有看的更远,因为有更好的解决方案。

建议:


#include <stdbool.h>
#include <string.h>

bool isPalindrome( const char* str )
{
    bool is_palindrome = true ;
    size_t rev = strlen( str ) - 1 ;
    size_t fwd = 0 ;
    
    while( is_palindrome && fwd < rev )
    {
        is_palindrome = (str[fwd] == str[rev]) ;
        fwd++ ;
        rev-- ;
    }

    return is_palindrome ;
}

使用中:

int main()
{
    const char* test[] = { "xyyx", "xyayx", "xyxy", "xyaxy" } ;
    for( size_t t = 0; t < sizeof(test)/sizeof(*test); t++ )
    {
        printf("%s : %s palindrome\n", test[t], 
                                       isPalindrome( test[t] ) ? "Is" : "Is not" ) ;
    }
    
    return 0;
}

输出:

xyyx : Is palindrome
xyayx : Is palindrome
xyxy : Is not palindrome
xyaxy : Is not palindrome

【讨论】:

  • @SOORAJSR 欢迎您,但请注意:meta.stackexchange.com/questions/126180/…(赞成/接受首选)。
  • 我完全是一个菜鸟程序员,还在学习东西。你的回答帮助我找到了我犯的错误。
【解决方案3】:

第一个算法

您在第一个程序中使用的算法涉及将每个字母与其他每个字母进行比较,这无助于确定数字是否为回文并且似乎无法修复。

第二种算法

然而,第二种方法的问题是您总是将name[i] 与name[length] 进行比较。而是将其更改为length-i-1。这将从length-1 开始比较,并在每次下一次迭代中将字符的长度减1:

for(i = 0;i <= length / 2;i++)
{
    if(name[i] != name[length-i-1])
    {
        flag=1;
        break;
    }
}

gets() 和缓冲区溢出

不要使用gets。此方法易受缓冲区溢出的影响。如果您输入的字符串长度超过 100 个字符,则会导致未定义的行为。使用fgets 代替确定性行为:

fgets(name, sizeof(name), stdin);

这会占用缓冲区的大小,并且最多只能读取sizeof(name) 个字符。

完整代码

理想情况下,您应该考虑包装逻辑以检查字符串是否为函数中的回文:

int is_palindrome(char*);

int main(void) 
{
    char name[100];
    setbuf(stdout,NULL);
    printf("Enter your name");
    fgets(name, sizeof(name), stdin);
    
    if(is_palindrome(name))
    {
        printf("The given word is a palindrome");
    }
    else
    {
        printf("This is NOT a palindrome word");
    }
    return 0;
    
}

int is_palindrome(char* name)
{
    int length = strlen(name);
    int flag = 0, i;
    for(i = 0;i <= length / 2; i++)
    {
        if(name[i]!=name[length-i-1])
        {
            return 0;
        }
    }
    return 1;
}

【讨论】:

  • 您需要测试以删除fgets() 包含的'\n' 行尾。否则没有输入是回文的。由于输入法并不是问题的一部分(即使 OP 代码显然很危险),避免它并显示带有字符串常量的测试会更简单。也建议int is_palindrome( const char* name )。
猜你喜欢
  • 1970-01-01
  • 2013-04-29
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 2015-11-21
  • 2012-04-05
相关资源
最近更新 更多