4

I was preparing for my interview and started working from simple C programming questions. One question I came across was to check if a given string is palindrome. I wrote a a 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. 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);
}
LihO
  • 41,190
  • 11
  • 99
  • 167
Ani
  • 149
  • 1
  • 1
  • 8

4 Answers4

6

"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. 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:

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>

LihO
  • 41,190
  • 11
  • 99
  • 167
  • Wow thats neat.Straight forward. – Ani Oct 07 '13 at 16:32
  • 1
    When pointers points to same char in the middle, they are obviously equal, so correct condition should be `ptr2 > ptr1`. Also you don't need to handle strings of length 1 in this case. – meownoid Sep 10 '16 at 09:21
0

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;
}
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
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;
}
Dave2e
  • 22,192
  • 18
  • 42
  • 50
hbkvikas
  • 69
  • 4
-1

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. 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);
}
Sergey L.
  • 21,822
  • 5
  • 49
  • 75
  • Can u elaborate on "Check for odd string length, odd stings can't be palindromes"? How about "Madam" string length is 5 and is a palindrome right? – Ani Oct 07 '13 at 16:21
  • @Ani OK, this will depend on your technical definition of palindrome, but in the theoretical computer science world a palindrome is a word of even length that can be decomposed into another word and it's reverse: `w` is a palindrome if exists a `v` such that `w = vv^{rev}` – Sergey L. Oct 07 '13 at 16:26