tags:

views:

307

answers:

4

I've been working through potential interview questions and one of them was to write a function in C to detect whether a given string was a palindrome or not.

I've gotten a pretty good start on it:

#include <stdio.h>
#include <stdbool.h>

bool isPalindrome(char *value);

bool isPalindrome(char *value)
{
    if (value == null)
        return false;

    char *begin = value;
    char *end = begin + strlen(value) - 1;

    while(*begin == *end)
    {
        if ((begin == end) || (begin+1 == end))
            return true;

        begin++;
        end--;
    }

    return false;
}


int main()
{
    printf("Enter a string: \n");
    char text[25];
    scanf("%s", text);

    if (isPalindrome(text))
    {
        printf("That is a palindrome!\n");
    }
    else
    {
        printf("That is not a palindrome!\n");
    }
}

However, I now want to ensure that I ignore spaces and punctuation.

What is the best way, given the code I have written above, to advance the pointers forward or backward should they encounter punctuation/spaces?

+5  A: 

change the loop to

while(begin < end) {
  while(ispunct(*begin) || isspace(*begin))
    ++begin;
  while(ispunct(*end) || isspace(*end))
    --end;
  if(*begin != *end)
    return false;
  ++begin;
  --end;
}
return true;
Alex Martelli
+1 but instead of `ispunct(x) || isspace(x)` I would probably use `!isalpha(x)`. It's slightly different, but it's a bit easier on the eyes in my opinion.
Chris Lutz
This will fail on a string composed entirely of punctuation (among others). You need more checks in those loops, to ensure that `end` and `begin` don't pass each other while skipping punctuation.
caf
Alex Martelli
@chris, `!isalpha` would also skip digits, which is not what the OP's specs say -- only whitespace and punctuation are to be skipped.
Alex Martelli
`isalnum`, then?
jbcreix
@Alex - This is true, I was getting my functions mixed up. I meant `isalnum` like @jbcreix said.
Chris Lutz
A: 

How about writing another function to remove the space and punctuation chars in a string?

Yin Zhu
Well, I could do that. I guess it just seemed like it made more sense if I consumed them by advancing the pointer.
Waldrop
Agree; it's definitely better not to allocate space for a new copied string if you don't need to.
Brooks Moses
+3  A: 

Inside the while loop, just skip over any characters you want to ignore:

while(*begin == *end)
{
    while ((begin != end) && (isspace(*begin) || isX(*begin))
        ++begin;

   // and something similar for end

One other comment. Since your function is not modifying the parameter, you should define it as:

bool isPalindrome(const char *value);
R Samuel Klatchko
+1: For adding "const " in the signature. On the same principle, "const char * begin" and "const char * end"!
ArunSaha
A: 
pavun_cool
@pavun_cool, you didn't read the question. This solution doesn't handle spaces or punctuation at all.
Waldrop