Introduction
In this lab, you will learn how to check if a string is a palindrome in Java. We will explore different approaches, starting with the fundamental method of reversing a string and comparing it to the original.
Building upon this, you will then learn a more efficient technique using the two-pointer approach. Finally, we will enhance our palindrome check to ignore case and non-letter characters, making the check more robust.
Reverse String and Compare
In this step, we will start by creating a simple Java program to reverse a string and then compare it with the original string. This is a fundamental step towards understanding string manipulation in Java and will serve as a building block for checking if a string is a palindrome.
First, let's create a new Java file. In the File Explorer on the left side of the WebIDE, right-click in the ~/project directory, select "New File", and name it StringReverse.java.
Now, open the StringReverse.java file in the editor and add the following code:
public class StringReverse {
public static void main(String[] args) {
String originalString = "hello";
String reversedString = "";
// Loop through the original string from end to beginning
for (int i = originalString.length() - 1; i >= 0; i--) {
// Append each character to the reversedString
reversedString += originalString.charAt(i);
}
System.out.println("Original string: " + originalString);
System.out.println("Reversed string: " + reversedString);
// Compare the original and reversed strings
if (originalString.equals(reversedString)) {
System.out.println("The string is the same forwards and backwards.");
} else {
System.out.println("The string is NOT the same forwards and backwards.");
}
}
}
Let's break down this code:
String originalString = "hello";: We declare aStringvariable namedoriginalStringand assign it the value "hello".String reversedString = "";: We declare an emptyStringvariable namedreversedString. We will build the reversed string here.for (int i = originalString.length() - 1; i >= 0; i--): This is aforloop that starts from the last character of theoriginalString(indexlength() - 1) and goes down to the first character (index 0).reversedString += originalString.charAt(i);: Inside the loop,originalString.charAt(i)gets the character at the current indexi. We then append this character to thereversedString.System.out.println(...): These lines print the original and reversed strings to the console.if (originalString.equals(reversedString)): Thisifstatement compares theoriginalStringandreversedStringusing theequals()method. In Java, you should useequals()to compare the content of strings, not the==operator.- The
ifandelseblocks print different messages based on whether the strings are the same.
Save the StringReverse.java file (Ctrl+S or Cmd+S).
Now, open the Terminal at the bottom of the WebIDE. Make sure you are in the ~/project directory. If not, type cd ~/project and press Enter.
Compile the Java code using the javac command:
javac StringReverse.java
If there are no errors, a StringReverse.class file will be created in the ~/project directory.
Finally, run the compiled Java program using the java command:
java StringReverse
You should see output similar to this:
Original string: hello
Reversed string: olleh
The string is NOT the same forwards and backwards.
In this case, "hello" is not the same forwards and backwards, so the program correctly identifies that.
Use Two-Pointer Approach for Palindrome
In the previous step, we reversed the entire string to check if it was a palindrome. While this works, it requires creating a new string, which can be inefficient for very long strings. A more efficient approach is to use the two-pointer technique.
The two-pointer technique involves using two pointers (variables that hold index positions) that start at different ends of the string and move towards the center. We compare the characters at these pointers. If they are always the same as the pointers move inwards, the string is a palindrome. If we find any mismatch, it's not a palindrome.
Let's create a new Java program to implement this. In the File Explorer on the left, create a new file named PalindromeChecker.java in the ~/project directory.
Open PalindromeChecker.java and add the following code:
public class PalindromeChecker {
public static void main(String[] args) {
String testString = "madam"; // Let's test with a palindrome
boolean isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
testString = "racecar"; // Another palindrome
isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
testString = "hello"; // Not a palindrome
isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
}
// Method to check if a string is a palindrome using two pointers
public static boolean checkPalindrome(String str) {
// Initialize two pointers
int left = 0; // Pointer starting from the beginning
int right = str.length() - 1; // Pointer starting from the end
// Loop while the left pointer is less than the right pointer
while (left < right) {
// Compare characters at the left and right pointers
if (str.charAt(left) != str.charAt(right)) {
// If characters don't match, it's not a palindrome
return false;
}
// Move the pointers inwards
left++;
right--;
}
// If the loop completes without finding any mismatch, it's a palindrome
return true;
}
}
Here's what's happening in the new code:
- We've created a separate method called
checkPalindromethat takes aStringas input and returns aboolean(true if it's a palindrome, false otherwise). This makes our code more organized and reusable. - Inside
checkPalindrome, we initializeleftto 0 (the index of the first character) andrighttostr.length() - 1(the index of the last character). - The
while (left < right)loop continues as long as the left pointer is to the left of the right pointer. if (str.charAt(left) != str.charAt(right))compares the characters at the currentleftandrightpositions. If they are different, we immediately know it's not a palindrome and returnfalse.- If the characters match, we move the pointers inwards:
left++increments the left pointer, andright--decrements the right pointer. - If the loop finishes without returning
false, it means all the compared characters matched, so the string is a palindrome, and we returntrue. - In the
mainmethod, we callcheckPalindromewith different test strings and print the results.
Save the PalindromeChecker.java file.
Now, compile and run the program in the Terminal:
javac PalindromeChecker.java
java PalindromeChecker
You should see the following output:
"madam" is a palindrome.
"racecar" is a palindrome.
"hello" is not a palindrome.
This demonstrates how the two-pointer approach efficiently checks for palindromes without reversing the entire string.
Ignore Case and Non-Letters in Palindrome
In the previous step, our palindrome checker worked for simple strings like "madam" and "racecar". However, real-world palindromes often ignore capitalization and punctuation. For example, "A man, a plan, a canal: Panama" is considered a palindrome.
In this step, we will enhance our PalindromeChecker to handle these cases by ignoring non-letter characters and treating uppercase and lowercase letters the same.
Open the PalindromeChecker.java file in the WebIDE editor. We will modify the checkPalindrome method.
Replace the existing checkPalindrome method with the following updated version:
// Method to check if a string is a palindrome using two pointers,
// ignoring case and non-letter characters
public static boolean checkPalindrome(String str) {
// Initialize two pointers
int left = 0; // Pointer starting from the beginning
int right = str.length() - 1; // Pointer starting from the end
// Loop while the left pointer is less than the right pointer
while (left < right) {
// Move left pointer past non-letter characters
while (left < right && !Character.isLetter(str.charAt(left))) {
left++;
}
// Move right pointer past non-letter characters
while (left < right && !Character.isLetter(str.charAt(right))) {
right--;
}
// If left and right pointers haven't crossed and characters don't match (ignoring case)
if (left < right && Character.toLowerCase(str.charAt(left)) != Character.toLowerCase(str.charAt(right))) {
// If characters don't match, it's not a palindrome
return false;
}
// Move the pointers inwards
left++;
right--;
}
// If the loop completes without finding any mismatch, it's a palindrome
return true;
}
Here are the changes we made:
- We added two
whileloops inside the mainwhile (left < right)loop. - The first inner
whileloop (while (left < right && !Character.isLetter(str.charAt(left)))) moves theleftpointer forward as long as it's still to the left of therightpointer and the character at theleftpointer is not a letter (!Character.isLetter(...)). - The second inner
whileloop (while (left < right && !Character.isLetter(str.charAt(right)))) moves therightpointer backward as long as it's still to the left of therightpointer and the character at therightpointer is not a letter. - The comparison
if (left < right && Character.toLowerCase(str.charAt(left)) != Character.toLowerCase(str.charAt(right)))now includes two important checks:left < right: This ensures we only compare characters if the pointers haven't crossed after skipping non-letters.Character.toLowerCase(...): This converts both characters to lowercase before comparing them, effectively ignoring case.
- If the characters (after converting to lowercase) don't match, we return
false. - If they match, we move both pointers inwards (
left++,right--) to check the next pair of characters.
Now, let's modify the main method to test with a string that includes spaces, punctuation, and mixed case. Replace the existing test cases in the main method with this:
public static void main(String[] args) {
String testString = "A man, a plan, a canal: Panama"; // A classic palindrome
boolean isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
testString = "No 'x' in Nixon"; // Another palindrome
isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
testString = "hello world"; // Not a palindrome
isPalindrome = checkPalindrome(testString);
if (isPalindrome) {
System.out.println("\"" + testString + "\" is a palindrome.");
} else {
System.out.println("\"" + testString + "\" is not a palindrome.");
}
}
Save the PalindromeChecker.java file.
Compile and run the updated program in the Terminal:
javac PalindromeChecker.java
java PalindromeChecker
You should now see the following output, correctly identifying the palindromes even with non-letter characters and mixed case:
"A man, a plan, a canal: Panama" is a palindrome.
"No 'x' in Nixon" is a palindrome.
"hello world" is not a palindrome.
You have successfully enhanced your palindrome checker to handle more complex strings!
Summary
In this lab, we learned how to check if a string is a palindrome in Java. We started by implementing a method to reverse a string and comparing it to the original string to determine if it's a palindrome. This involved creating a Java file, writing code to iterate through the string in reverse, and using the equals() method for comparison.
We then explored the two-pointer approach, a more efficient method for palindrome checking that avoids creating a new reversed string. Finally, we enhanced our palindrome check to ignore case and non-letter characters, making the check more robust for real-world scenarios.



