HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Palindrome checker using a sentinel loop

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
looppalindromeusingsentinelchecker

Problem

This is my first submission and have completed one quarter of Java programming.

I have an assignment to create a Palindrome Checker. Fairly straight forward, I had that portion of the code figured out in the first hour. However, in typical fashion (for me) I want my code to do a bit more. This is where I run into issues.

I want this code to do the following:

  • Take user input.



  • Correctly identify if the input is a palindrome regardless of case or punctuation.



  • Run in a loop so that multiple tests can be performed.



So far it works, I just don't know if I went about it the right way. Is this inefficient? Are there obvious rookie mistakes?

```
/**
* Created by Travis on 1/10/2015.
*/

import java.io.IOException;
import java.util.*;
import javax.swing.*;
import java.text.*;
import java.lang.StringBuilder;

public class Palindrome
{
public static void main(String[] args) throws IOException //main class
{
String str = "", answer = "", test1 = "yes", test2 = "no"; //strings

int len = 10; //initial value for len so it doesn't trip the success if

Scanner KB = new Scanner(System.in); //user input

System.out.println("Greetings, Welcome to the Palindrome Checker.\n" + //initial greeting
"Would you like to check a Palindrome? (Yes or no)");

answer = KB.nextLine(); //input is for the sentinel program.

if (!(answer.equalsIgnoreCase(test1) || answer.equalsIgnoreCase(test2))) //error message in case user inputs incorrect string.
{
System.out.println("Error! You can only choose 'yes' or 'no'. Please try again:");
answer = KB.nextLine(); //allows for new answer
}

System.out.println(answer + " y"); //debugging so i can see answer

while (answer.equalsIgnoreCase(test1)) //compares to test1 which is: yes. as long as answer equals yes, the program should loop
{
System.out.println("Please provide a word or phrase:");

Solution

Employ Java API

Why not keep it simple? StringBuilder has a built-in reverse method that you can use to make a method like:

private static boolean isPalindrome(String str) {
   return str.equalsIgnoreCase(
        new StringBuilder(str).reverse().toString()
   );
}


better yet extract the logic and have one method to reverse a string:

private static String reverse(String input) {
        return new StringBuilder(input).reverse().toString();
}


which would simplify the method to:

private static boolean isPalindrome(String str) {
       return str.equalsIgnoreCase(reverse(str));
}


Apply simple Regex functions for syntax requirements

Since you also want to ignore all punctuation instead of consecutively calling replaceAll for spaces and non-word characters you can just call (replaceAll("[^a-zA-Z]", "") which would, on top of removing all spaces and non-word characters as you desire, also discard numbers (anything that isn't a-z, A-Z). Though I don't know how I feel about "ra@!#33!cec!(*@--..!ar" being a valid palindrome.

Caveat: If you choose to go with the method the above, I'd also check if the string only contains otherwise ignored characters so you don't get false positives (empty or all nonsense strings reported as true).

Putting it all together the overall method would look like:

public static boolean isPalindrome(String str) {
        String possiblePalindrome = str.replaceAll("[^a-zA-Z]", "");
        return possiblePalindrome.length() == 0 ?
            false : possiblePalindrome.equalsIgnoreCase(reverse(possiblePalindrome));
}


On organization & programming approach

Building something like this for the sake of understanding is definitely something to be applauded. Good on you for doing so, and definitely keep it up! Do, however, note the importance of evaluating what's already available. The entire program is fully encompassed by the application of three functions the native libraries afford you, but this is clearly the small part of a greater whole.

In the future, consider doing a bit of research on what conventional libraries make available to you so you may focus on the implementation for your specific purpose rather than worrying about the minute details. It may not be obvious but this concentrated approach results in a better accrual of wisdom.

Separation of concerns

Pretty much all your code is in main(), it would benefit maintainability and readability if you moved some of the responsibilities outside. For instance, your entire for and while validation loops could just be one method that threw an IllegalArgumentException that could simply call the method again to ensure correct input.

Why do you import javax.swing. and java.text. libraries? They are unused.

On convention

It's Java standard to have the braces follow the class and method names, like so:

public class Palindrome {


This is the case anytime you use the curly braces, including your loops, with the additional caveat that else, catch, and other "paired" statements are preceded by their preceding statement's closing brace, like so:

if (condition) {
    // do something
} else {
    // do something else
}


Although it's a definite plus that you're consistent about it, this is a minor adjustment that would make your code more readable, especially if you intend to share it.

Code Snippets

private static boolean isPalindrome(String str) {
   return str.equalsIgnoreCase(
        new StringBuilder(str).reverse().toString()
   );
}
private static String reverse(String input) {
        return new StringBuilder(input).reverse().toString();
}
private static boolean isPalindrome(String str) {
       return str.equalsIgnoreCase(reverse(str));
}
public static boolean isPalindrome(String str) {
        String possiblePalindrome = str.replaceAll("[^a-zA-Z]", "");
        return possiblePalindrome.length() == 0 ?
            false : possiblePalindrome.equalsIgnoreCase(reverse(possiblePalindrome));
}
public class Palindrome {

Context

StackExchange Code Review Q#77220, answer score: 10

Revisions (0)

No revisions yet.