Since we had tested anagrams, it seems fair we give the palindrome check problem a go. How to check if a string is a palindrome? My solution is shown at the bottom in C#, Java, Objective-C, Swift 2, and C++.

observations

By definition a palindrome is word or phrase that is the same reversed ignoring lettercase, spaces, and punctuation. Other symbols and numbers count. Some examples:

  • Madam, I’m Adam.
  • Never odd or even.
  • Rise to vote, sir!
  • Salas
  • 191

assumptions

Let’s assume a single-character word is a palindrome. An empty string, or string containing only punctuation, wouldn’t be a word or phrase, so we won’t include them.

program

Remember to check for valid input. Like in the anagram test, we’ll use a regular expression to remove punctuation. A simple method is to iterate from the beginning of the string, and for each character check to see if the mirrored position from the end is the same character.


C#

C#: is the string a palindrome?
static bool IsPalindrome(string phrase)
{
// remember to check for null
if (phrase != null && phrase.Length > 0)
{
// spaces and punctuation don't count, but include symbols
phrase = System.Text.RegularExpressions.Regex.Replace(phrase, "[\\s\\p{P}]", "");
// we could also compare ignoring case during the for-loop below.
phrase = phrase.toLower();
int len = phrase.Length;
if (len > 1)
{
// iterate to the midpoint and check if char same as
// on mirrored from end position
for (int i = 0; i < len / 2 + 1; ++i)
{
if (phrase[i] != phrase[len - i - 1])
{
return false;
}
}
return true;
}
else if (len == 1)
{
return true;
}
}
return false;
}

Java

Java: is the string a palindrome?
public class StringProblems
{
static boolean isPalindrome(String phrase)
{
if (phrase != null && phrase.length() > 0) {
// spaces and punctuation don't count
// replace using regular expression
String pattern = "[\\s\\p{P}]";
phrase = phrase.replaceAll(pattern, "");
phrase = phrase.toLowerCase();
int len = phrase.length();
if (len == 1) {
return true;
}
else if (len > 1) {
for (int i = 0; i < len / 2 + 1; ++i) {
if (phrase.charAt(i) != phrase.charAt(len - i - 1)) {
return false;
}
}
return true;
}
}
return false;
}
}

Objective-C

Objective-C: is the string a palindrome?
+ (BOOL)isPalindrome:(NSString *)phrase
{
if (phrase) {
// remove spaces, punctuation
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[\\s\\p{P}]"
options:NSRegularExpressionCaseInsensitive error:&error];
phrase = [regex stringByReplacingMatchesInString:phrase
options:0
range:NSMakeRange(0, phrase.length)
withTemplate:@""];
if (phrase.length > 1) {
phrase = [phrase lowercaseString];
// go to mid-point while checking for same character on other end
for (int i = 0; i < phrase.length / 2 + 1; ++i) {
if ([phrase characterAtIndex:i] != [phrase characterAtIndex:(phrase.length - i - 1)]) {
return NO;
}
}
return YES;
}
else {
return YES;
}
}
return NO;
}

Swift 2

Swift 2: is the string a palindrome?
import Cocoa
func phraseIsPalindrome(phrase: String) -> Bool
{
let regex = try! NSRegularExpression(pattern: "[\\s\\p{P}]", options: [.CaseInsensitive])
let trimmedPhrase = regex.stringByReplacingMatchesInString(phrase, options:[], range: NSMakeRange(0, phrase.characters.count), withTemplate: "")
if trimmedPhrase.characters.count > 1 {
let charArray = Array(trimmedPhrase.lowercaseString.characters)
// go to mid-point while checking for same character on other end
for i in 0 ..< len / 2 + 1 {
if charArray[i] != charArray[charArray.count - i - 1] {
return false
}
}
return true
}
else if trimmedPhrase.characters.count == 1 {
// allow single-character phrase
return true
}
return false
}
phraseIsPalindrome("Never odd or even.") // true
phraseIsPalindrome("Never odd or evan") // false
phraseIsPalindrome("Madam, I'm Adam!") // true

Swift 3

Swift 3: is the string a palindrome?
import Cocoa
var str = "Never odd or even."
func IsPalindrome(phrase: String) -> Bool
{
let regex = try! RegularExpression(pattern: "[\\s\\p{P}]", options: [.caseInsensitive])
let trimmedPhrase = regex.stringByReplacingMatches(in: phrase, options: [], range: NSMakeRange(0, phrase.characters.count), withTemplate: "")
let len = trimmedPhrase.characters.count;
if (len > 1) {
let charArray = Array(trimmedPhrase.lowercased().characters)
for i in 0 ..< len / 2 + 1 {
if charArray[i] != charArray[len - i - 1] {
return false;
}
}
return true;
}
else if (len == 1) {
return true;
}
return false;
}
IsPalindrome(phrase: str)

C++11 console

C++11: is the string a palindrome?
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <regex>
void TestString(std::string str);
bool IsPalindrome(std::string phrase);
int main()
{
TestString("Never odd or even?"); // true
TestString("Never odd or evan!"); // false
TestString("Madam, I'm Adam!"); // true
return 0;
}
void TestString(std::string str)
{
if (IsPalindrome(str))
{
std::cout << "'" << str << "' is a palindrome.\n";
}
}
bool IsPalindrome(std::string phrase)
{
if (phrase.length() > 0)
{
// spaces and punctuation don't count
// (see http://www.cplusplus.com/reference/regex/ECMAScript/ for patterns)
std::regex ex("[\\s[:punct:]]");
phrase = std::regex_replace(phrase, ex, "");
// force lowercase
std::transform(phrase.begin(), phrase.end(), phrase.begin(), ::tolower);
int len = phrase.length();
if (len > 1)
{
// iterate to middle and check of char is same on mirrored side
for (int i = 0; i < len; i++)
{
if (phrase[i] != phrase[len - i - 1])
{
return false;
}
}
return true;
}
else if (len == 1)
{
// assumed a palindrome
return true;
}
}
return false;
}