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 (updated for 5), 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#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
+ (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 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import UIKit

var stringList: [String] = ["Tom Marvolo Riddle", "School master"]

stringList.append("I am Lord Voldemort!")
stringList.append("the classroom")
stringList.append("Madam, I'm Adam.")
stringList.append("Ray-Adverb")
stringList.append("Ray adverb")
stringList.append("191")
stringList.append("Never odd, or even?")
stringList.append("Astronomer!!")
stringList.append("moon starer?")
stringList.append("Dave Barry")

for str1 in stringList {
   
    if (isPalindrome(phrase1: str1)) {
        print("'" + str1 + "' is a palindrome")
    }
}

func isPalindrome(phrase1: String) -> Bool {
    
    if (phrase1.count > 0) {
        
        // define regular expression to remove spaces and punctuation
        let regex = try! NSRegularExpression(pattern: "[\\s\\p{P}]", options: [.caseInsensitive])
        let trimmedPhrase = regex.stringByReplacingMatches(in: phrase1, options: [], range: NSMakeRange(0, phrase1.count), withTemplate: "")
        
        let len = trimmedPhrase.count
        
        if (len == 1) {
            return true
        }
        else if (len > 1) {
            
            // make a lower-case character array to compare
            let chArr1 = Array(trimmedPhrase.lowercased())
           
            for i in 0 ..< len / 2 + 1 {
                if (chArr1[i] != chArr1[len - i - 1]) {
                    return false
                }
            }
            return true
        }
    }
    return false
}

C++11 console

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#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;
}