Palindrome: Java & Ruby /24 January 2008 @ 3pm
One thing that programming students often have to implement is a program to tell whether or not a string is a palindrome. In this post I flex my dusty Java and demonstrate a simple palindrome detector.
Java
First off just in case you are not sure, a palindrome is a string that reads the same forwards as it does backwards. e.g madam
So to solve this I guess we need a method called pallindrome()
public static boolean isPalindrome (String word) {
if (word.equalsIgnoreCase(reverse(word))) { return true; }
else { return false; }
}
So here we have a method called isPalindrome that takes a string and returns true or false depending on the success of the if statement. The line that performs the test is:
word.equalsIgnoreCase(reverse(word))
This uses the Java String method equalsIgnoreCase to test if word is equal to the result of reverse(word). If true then it is a palindrome.
So what is missing from this code? the implementation of the reverse method. There are many ways to reverse a String, below is my first attempt
public static String reverse (String in) {
String out = "";
for (int i=0; i<in.length(); i++) {
out += String.valueOf(in.charAt((in.length()-1)-i));
}
return out;
}
This is a typical loop through the characters in a string in reverse and build up another string with these characters and then return this new string. All fine and good, then I googled a bit and found out that the Java StringBuffer object has a native reverse method so I can rewrite the method as follows:
public static String reverse (String in) {
StringBuffer sb = new StringBuffer(in).reverse();
return sb.toString();
}
As well as being fewer lines of code this is far more clear than a the for loop method.
Things to take note of
The reason I split the palindrome method and reverse method instead of having them as one was to improve the testability of the code. It also increases the chances of reuse as it is forceable that I may want the reverse method at a later date on it own without the palindrome stuff.
This is not a perfect implementation. The second to you stick more than one word into isPalindrome it will fall down because at the moment it will not ignore space characters so a palindrome such as ‘nurses run’ will return false
It may not be totally perfect but I enjoyed the exorcise and feel it must be better than the version I came up with 6 years ago on my introduction to programming course.
Ruby
Yes yes, I know another Ruby version of perfectly good code, but the main reason I include it is that its really cool (well for me anyway). This is because the Ruby String object has a reverse method already and because of the open nature of Ruby classes you can add a palindrome method to Ruby’s String without any inheritance stuff. Take a look:
class String
def palindrome?
self == self.reverse
end
end
"madam".palindrome? # returns true
I really like this method, but of course with great power comes great responsibility and open classes are not always a good idea.
Update
So reading more into this it appears that the Java string buffer method might be faster and more efficient than the loop method. The reason for this is that when Java converts the loop method into byte code it substitutes the string concatenation operator for a string buffer and uses the append method. It does this for every concat operation and uses the default buffer size of 16 characters.
Some other factors to take into consideration are that if a null string, empty string or a single character are passed in. A null string will cause a NullPointerException so it is important that it is dealt with. If an empty or one character string is entered they should be returned strait away and no string buffer object created because they are already a reverse of them selves. This means a slight change to the method:
public static String reverse (String str) {
if (str == null) {
// kick out an error
throw new NullPointerException( "reverse passed null String" );
} else if (str.length() <= 1) {
// string is already revesed
return str;
}
// use the StringBuffer to reverse str
return new StringBuffer(str).reverse().toString();
}
Here are some good resources on this topic. I really love the way that you can google something and it turns up a load of stuff that can really help in how you approach a problem and give advice on the merits of different solutions. It really helps improve you.
- StringBuffer versus String
- Optimizing string operations
- NullPointerExceptions
- A great blog on reversing strings with java
Lastly I tried a few different Java methods for reversing a String. You can find the results here.
2 Comments