【问题标题】:Checking for palindrome string in c在c中检查回文字符串
【发布时间】:2010-08-12 19:05:32
【问题描述】:

我接受一个字符串作为命令行参数。我想检查输入的字符串是否是回文并打印结果。我已经编写了以下代码。但它显示所有输入的结果“不是回文”。

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

int main(int argc, char argv[20]) {
    int i;
    int l = strlen(argv);    
    char str[20];
    bzero(str, 20);

    for(i=0; i<l; i++)
    {
        str[i] = argv[i+2];
    } 
    int flag;
    int len = strlen(str);
    for(i=0; i< len/2; i++)
    {
        if(str[i] == str[len - (i+2)])
        {
            flag = 0;
        }
        else
        {
            flag = 1;
            break;
        }
    }

    if(flag == 0)
        printf("Palindrome\n");
    else
        printf("Not a palindrome\n");
}

【问题讨论】:

  • 我无法在此处格式化代码。有人可以帮我解决编程问题吗?如何在不同的行上打印每一行代码?
  • 要格式化您的代码,使用四个空格缩进,或使用 101010 按钮。它不像现在这样可读。
  • @user417316,从您使用的任何编辑器将代码粘贴到文本框中,全选,然后选择代码格式化按钮(看起来像小 1 和 0)。
  • 不是您问题的答案,但无需在每次成功迭代时重置 flag。只需初始化它,仅在失败时更改它。此外,argv 的类型错误,应该是 char**;这可能会造成几乎任何形式的破坏。
  • @Thomas:谢谢!!它有帮助。 @Carl Norum:谢谢你的帮助!! @dmckee:谢谢!

标签: c palindrome


【解决方案1】:

您可以通过在 for-loop 中使用两个偏移迭代器来以 K&R 样式执行此操作:

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

int main(int argc, char *argv[]) {
    assert(argc != 1);

    char *text = argv[1];

    int len = strlen(text);
    int is_palindrome = 1;
    int i, j;

    for(i = 0, j = len - 1; i < len / 2; i++, j--) {
        if(text[i] != text[j]) {
            is_palindrome = 0;
            break;
        }
    }

    printf("%s a palindrome.\n", is_palindrome ? "is" : "isn't");

    return(0);
}

与原来的变化:

  • 按照 tenfour 的建议将 shift(len >> 1) 更改为 division(len / 2)。

【讨论】:

  • 实际上我不太习惯使用指针进行编程。我需要获得更多信息和对指针的理解。也许那时我会尝试使用指针进行编程。有没有其他方法可以解决回文问题?
  • 优化:int len = strlen(text) / 2;
  • 我要推荐Binky的指针趣味视频:cslibrary.stanford.edu/104
【解决方案2】:

基于 cmets 更新:

int is_palindrome(const char *s)
{
   const char *t = s + strlen(s);
   while (s<t && *s==*--t) s++;
   return s>=t;
}

而且由于 OP 想要一个指针不那么重的版本:

int is_palindrome(const char *s)
{
   size_t i=0, j = strlen(s);
   while (i<j && s[i]==s[--j]) i++;
   return i>=j;
}

作为参考,这是原始的错误版本:

int is_palindrome(const char *s)
{
   const char *t = s + strlen(s) - 1;
   while (s<t && *s++==*t--);
   return s>=t;
}

【讨论】:

  • 我不认为这很神秘。我称之为不做一顿饭。当你有一个微不足道的任务要执行时,不要写这么多让它看起来很复杂......除非你试图偷懒并说服你的老板你已经写了一堆“代码行”。跨度>
  • 不幸的是,对于很多像“ab”这样的非回文数,它都失败了。试试while (*s == *t &amp;&amp; s++ &lt; t--) ;。检查空字符串存在问题。
  • 当字符串为空时,我正在等待有人在字符串开头之前捕捉到递减t 的技术性。 :-) 你对另一个错误是正确的——这就是我在 SO 的文本框中编码所得到的。我会把它改成for (t=s+strlen(s)-1; s&lt;t &amp;&amp; *s==*t; s++, t--);
  • 实际上我不太习惯使用指针进行编程。我需要获得更多信息和对指针的理解。也许那时我会尝试使用指针进行编程。有没有其他方法可以解决回文问题?
  • 好的,我将添加一个带有数组索引的版本。
【解决方案3】:

一方面,您对main 的签名已关闭。它应该是int main(int argc, char** argv)int main(int argc, char * argv[])。您将指向字符串的指针视为字符串。

当你改变它时,你想要的字符串应该在argv[1] 中(因为argv[0] 是程序名称的某种表示形式)。

【讨论】:

  • 其实我试过 int main(int argc, char** argv)。但它给了我一些铸造错误。我也在想办法。
  • @user: 那你需要弄清楚那个错误,因为 main 的签名是 mandated 的标准。
  • 我只使用了 argv[1]。但它仍然显示一些错误和警告。
  • @Khushboo:在这种情况下,请编辑问题以显示您修改后的代码以及错误和警告是什么。
【解决方案4】:

有一个很好的例子是使用指针而不是索引:

int is_palindrome(const char *s) {
    const char *end = s + strlen(s);
    while (end > s) {
        --end;
        if (*end != *s) return 0;
        ++s;
    }
    return 1;
}

如果你喜欢简短易混淆的代码,你可以重写:

int is_palindrome(const char *s) {
    const char *end = s + strlen(s);
    while (end > s) if (*(--end) != *(s++)) return 0;
    return 1;
}

argv 不是字符串,它是一个字符串数组,一个用于程序名称,一个用于每个参数(通常在命令行中以空格分隔)。所以要测试第一个参数是否是回文,你对 argv[1] 感兴趣。

int main(int argc, char **argv) {
    if (argc != 2) {
        printf("usage: %s <string>\n", argv[0]); // or something
        return 1;
    }
    if (is_palindrome(argv[1])) {
        printf("Palindrome\n");
    } else {
        printf("Not a Palindrome\n");
    }
}

【讨论】:

    【解决方案5】:

    第一个循环没有意义。 将字符串复制到另一个没有意义。

    只要这样做,调整索引:

    #include<stdio.h>
    #include<string.h>
    
    int main(int argc, char **argv) {
    int i;
    char * str = argv[1];
    int flag;
    
    int len = strlen(str);
    
    for(i=0; i< (len+1)/2; i++)
    {
    
        printf("DEBUG: Comparing %c %c\n",str[i], str[len - (i+1)]);
    
    
        if(str[i] == str[len - (i+1)])
        {
            flag = 0;
        }
        else
        {
            flag = 1;
            break;
        }
    }
    
        if(flag == 0)
        printf("Palindrome\n");
    else
        printf("Not a palindrome\n");
    }
    

    【讨论】:

      【解决方案6】:

      没有指针(除了用于复制原始字符串的指针)。

      #include    <stdio.h>
      #include    <string.h>
      
      int main( int argc, char *argv[] )
      {
          char    *s2;
      
          if ( argc != 2 )
              return ( 1 );   //  not properly invoked
      
          if ( (s2 = strdup( argv[1] )) == NULL )
              return ( 2 );   //  failed (not likely)
      
          printf( "\"%s\" %s a palindrome.\n", argv[1], strcmp( argv[1], strrev( s2 ) ) ? "is not" : "is" );
      
          free( s2 );
      
          return ( 0 );
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-02
        • 1970-01-01
        • 2021-09-15
        • 1970-01-01
        • 1970-01-01
        • 2012-04-05
        相关资源
        最近更新 更多