Solutions like these are great because they are easy to follow. The solutions with loops, stacks, etc. are nice but harder to inspect than this one.All this needs is a line or two to trim it down to a fixed alphabet (just [a-zA-Z] characters?).

With a strict definition of a palindrome, however, this works exactly. The definition does not specify what "reading the same in either direction" means, and as such, a strict character for character comparison, which this is, is the most simple algorithm.

Push half the chars onto a stack (Length / 2).
Pop and compare each char until the first unmatch.
If the stack has zero elements: palindrome.
*in the case of a string with an odd Length, throw out the middle char.

You said: Any correct solution needs to ignore whitespace and punctuation (and any non-alphabetic characters actually) and needs to be case insensitive. What makes you think that this is true? Does anybody have a correct definition of a palindrome? Following the definition of the questionnee, I don't agree with you.

That will return true for "racecar", "Racecar", "race car", "racecar ", and "RaCe cAr". It would be easy to modify to include symbols or spaces as well, but I figure it's more useful to only count letters(and ignore case). This works for all palindromes I've found in the answers here, and I've been unable to trick it into false negatives/positives.

Also, if you don't like bool in a "C" program, it could obviously return int, with return 1 and return 0 for true and false respectively.

One solution was inefficient because it passed an std::string by copy, and because it iterated over all the chars, instead of comparing only half the chars. Then, even when discovering the string was not a palindrome, it continued the loop, waiting its end before reporting "false".

The other was better, with a very small function, whose problem was that it was not able to test anything else than std::string. In C++, it is easy to extend an algorithm to a whole bunch of similar objects. By templating its std::string into "T", it would have worked on both std::string, std::wstring, std::vector and std::deque. But without major modification because of the use of the operator <, the std::list was out of its scope.

My own solutions try to show that a C++ solution won't stop at working on the exact current type, but will strive to work an anything that behaves the same way, no matter the type. For example, I could apply my palindrome tests on std::string, on vector of int or on list of "Anything" as long as Anything was comparable through its operator = (build in types, as well as classes).

Note that the template can even be extended with an optional type that can be used to compare the data. For example, if you want to compare in a case insensitive way, or even compare similar characters (like è, é, ë, ê and e).

Like king Leonidas would have said: "Templates ? This is C++ !!!"

So, in C++, there are at least 3 major ways to do it, each one leading to the other:

Solution A: In a c-like way

The problem is that until C++0X, we can't consider the std::string array of chars as contiguous, so we must "cheat" and retrieve the c_str() property. As we are using it in a read-only fashion, it should be ok...

Solution B: A more "C++" version

Now, we'll try to apply the same solution, but to any C++ container with random access to its items through operator []. For example, any std::basic_string, std::vector, std::deque, etc. Operator [] is constant access for those containers, so we won't lose undue speed.

Solution C: Template powah !

It will work with almost any unordered STL-like container with bidirectional iterators
For example, any std::basic_string, std::vector, std::deque, std::list, etc.
So, this function can be applied on all STL-like containers with the following conditions:
1 - T is a container with bidirectional iterator
2 - T's iterator points to a comparable type (through operator =)

If you don't have the reverse, then you have to allocate and then create it by copying the data. I guess that comparing the reverse is always slower, but for curiosity's sake, I'm interested in any "comparing the reverse" implementation.

This is all good, but is there a way to do better algorithmically? I was once asked in a interview to recognize a palindrome in linear time and constant space.

I couldn't think of anything then and I still can't.

(If it helps, I asked the interviewer what the answer was. He said you can construct a pair of hash functions such that they hash a given string to the same value if and only if that string is a palindrome. I have no idea how you would actually make this pair of functions.)

Plain English

The solutions which strip out any chars that don't fall between A-Z or a-z are very English centric. Letters with diacritics such as à or é would be stripped!

According to Wikipedia:

The treatment of diacritics varies. In languages such as Czech and Spanish, letters with diacritics or accents (except tildes) are not given a separate place in the alphabet, and thus preserve the palindrome whether or not the repeated letter has an ornamentation. However, in Swedish and other Nordic languages, A and A with a ring (å) are distinct letters and must be mirrored exactly to be considered a true palindrome.

So to cover many other languages it would be better to use collation to convert diacritical marks to their equivalent non diacritic or leave alone as appropriate and then strip whitespace and punctuation only before comparing.

set l = index of left most character in word
set r = index of right most character in word
loop while(l < r)
begin
if letter at l does not equal letter at r
word is not palindrome
else
increase l and decrease r
end
word is palindrome

Here are two more Perl versions, neither of which uses reverse. Both use the basic algorithm of comparing the first character of the string to the last, then discarding them and repeating the test, but they use different methods of getting at the individual characters (the first peels them off one at a time with a regex, the second splits the string into an array of characters).

Here's another for C# that I used when doing a sample server control. It can be found in the book ASP.NET 3.5 Step by Step (MS Press). It's two methods, one to strip non-alphanumerics, and another to check for a palindrome.

My 2c. Avoids overhead of full string reversal everytime, taking advantage of shortcircuiting to return as soon as the nature of the string is determined. Yes, you should condition your string first, but IMO that's the job of another function.