简体   繁体   English

在C中检查给定字符串是否为回文的有效方法

[英]Effective way of checking if a given string is palindrome in C

I was preparing for my interview and started working from simple C programming questions. 我正在准备我的面试,并从简单的C编程问题开始工作。 One question I came across was to check if a given string is palindrome. 我遇到的一个问题是检查给定的字符串是否是回文。 I wrote aa code to find if the user given string is palindrome using Pointers. 我写了一个代码来查找用户指定字符串是否是使用指针的回文。 I'd like to know if this is the effective way in terms of runtime or is there any enhancement I could do to it. 我想知道这是否是运行时方面的有效方法,还是我可以做的任何增强。 Also It would be nice if anyone suggests how to remove other characters other than letters (like apostrophe comas) when using pointer.I've added my function below. 如果有人建议如何在使用指针时删除除字母之外的其他字符(如撇号comas),那将是很好的。我在下面添加了我的功能。 It accepts a pointer to the string as parameter and returns integer. 它接受指向字符串的指针作为参数并返回整数。

int palindrome(char* string)
{
    char *ptr1=string;
    char *ptr2=string+strlen(string)-1;
    while(ptr2>ptr1){
        if(tolower(*ptr1)!=tolower(*ptr2)){
            return(0);
        }
        ptr1++;ptr2--;
    }
    return(1);
}

"how to remove other characters other than letters?" “如何删除字母以外的其他字符?”

I think you don't want to actually remove it, just skip it and you could use isalpha to do so. 我想你不想实际删除它,只是跳过它,你可以使用isalpha这样做。 Also note that condition ptr2 > ptr1 will work only for strings with even amount of characters such as abba , but for strings such as abcba , the condition should be ptr2 >= ptr1 : 另请注意,条件ptr2 > ptr1仅适用于具有偶数字符的字符串,例如abba ,但对于字符串(如abcba ,条件应为ptr2 >= ptr1

int palindrome(char* string)
{
    size_t len = strlen(string);

    // handle empty string and string of length 1:
    if (len == 0) return 0;
    if (len == 1) return 1;

    char *ptr1 = string;
    char *ptr2 = string + len - 1;
    while(ptr2 >= ptr1) {
        if (!isalpha(*ptr2)) {
            ptr2--;
            continue;
        }
        if (!isalpha(*ptr1)) {
            ptr1++;
            continue;
        }
        if( tolower(*ptr1) != tolower(*ptr2)) {
            return 0;
        }
        ptr1++; ptr2--;
    }
    return 1;
}

you might need to #include <ctype.h> 你可能需要#include <ctype.h>

How about doing like this if you want to do it using pointers only: 如果你只想使用指针做这样做,那怎么样:

int main()
{
 char str[100];
 char *p,*t;
 printf("Your string : ");
 gets(str);
 for(p=str ; *p!=NULL ; p++);
  for(t=str, p-- ; p>=t; )
  {
    if(*p==*t)
    {
        p--;
        t++;
    }
    else
        break;
  }
  if(t>p)
       printf("\nPalindrome");
  else
       printf("\nNot a palindrome");
  getch();
  return 0;
}
int main()
{   

const char *p = "MALAYALAM";

int count = 0;
int len = strlen(p);
for(int i = 0; i < len; i++ )
{
    if(p[i] == p[len - i - 1])
        count++;
}

cout << "Count: " << count;
if(count == len)
    cout << "Palindrome";
else
    cout << "Not Palindrome";

return 0;
}

I have actually experimented quite a lot with this kind of problem. 我实际上已经用这种问题进行了很多实验。

There are two optimisations that can be done: 有两种优化可以做到:

  • Check for odd string length, odd stings can't be palindromes 检查奇数字符串长度,奇怪的叮咬不能是回文
  • Start using vectorised compares, but this only really gives you performance if you expect a lot of palindromes. 开始使用矢量化比较,但如果您期望大量的回文,这只能真正为您提供性能。 If the majority of your strings aren't palindromes you are still best off with byte by byte comparisons. 如果您的大多数字符串不是回文,那么您仍然可以进行逐字节比较。 In fact my vectorised palindrome checker ran 5% slower then the non-vectorised just because palindromes were so rare in the input. 实际上,我的矢量化回文检查比非矢量化的速度慢了5%,因为回文中的回文非常罕见。 The extra branch that decided vectorised vs non vectorised made this big difference. 决定向量化与非向量化的额外分支产生了这么大的差异。

Here is code draft how you can do it vectorised: 以下是代码草案如何进行矢量化:

int palindrome(char* string)
{
    size_t length = strlen(string);

    if (length >= sizeof(uintptr_t)) { // if the string fits into a vector
        uintptr_t * ptr1 = (uintptr_t*)string;
        size_t length_v /= sizeof(uintptr_t);
        uintptr_t * ptr2 = (uintptr_t*)(string + (length - (length_v * sizeof(uintptr_t)))) + length_v - 1;

        while(ptr2>ptr1){
            if(*ptr1 != bswap(*ptr2)){ // byte swap for your word length, x86 has an instruction for it, needs to be defined separately
                return(0);
            }
            ptr1++;ptr2--;
        }

    } else {
        // standard byte by byte comparison
    }
    return(1);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM