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

Determining if a sentence is a palindrome

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

Problem

The biggest problem I see in checking palindromes on the Internet is when the user inputs a palindrome sentence or phrase and the program returns a wrong output. So for me, I tried to optimize palindrome checking by accepting sentences as input.

import java.io.*;

public class PalindromeCheck{

  public static void main(String[] args){

    BufferedReader dataIn = new BufferedReader(new InputStreamReader(System.in));
      try{

        System.out.print("Enter a sentence: ");
          String sentence = dataIn.readLine();
          PalCheck(sentence);

      }catch(IOException e){

        e.printStackTrace();
        System.err.println(e);

      }
    }

  public static void PalCheck(String s){

    String end = "";
    String result = s.replaceAll(" ", "");
     for ( int i = result.length() - 1; i >= 0; i-- )
       end = end + result.charAt(i);

        if (result.equalsIgnoreCase(end))
           System.out.println( result + " is a palindrome.");
        else
           System.out.println(result + " is not a palindrome.");

  }

}

Solution

The implementation given by @janos is a good one, but it is possible to improve it further. Specifically, most of the inefficiency arises from the single line:

char[] chars = string.replaceAll(" ", "").toLowerCase().toCharArray();


The replaceAll() method creates another copy of the string. Then, toLowerCase() creates another copy of the string. Finally, toCharArray() creates yet another copy in a character array of the resulting string. Of course, with the exception of the final result, the rest will get garbage collected. But each of the copies in an additional O(n) time.

Here is a suggestion:

private static boolean isPalindrome(String s) {
    int i = 0;
    int j = s.length() - 1;
    
    while (i < j) {
        if (Character.isWhitespace(s.charAt(i))) {
            i++;
            continue;
        }
        
        if (Character.isWhitespace(s.charAt(j))) {
            j--;
            continue;
        }
        
        if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) {
            return false;
        } else {
            i++;
            j--;
        }
    }
    return true;
}


I used the following test code to compare the performances of the two methods:

public class Main {

public static void main(String[] args) {

    String palindrome = "a b c de f g h x x xa b   a xxx     hg f e d c b  a";
    String nonPalindrome = "abcd e f g h  xxxabcxxx hgfe  d c ba";

    long start = System.currentTimeMillis();
    
    for (int i = 0; i < 1000000; i++) {
        Main.checkPalindrome(palindrome);
        Main.checkPalindrome(nonPalindrome);
    }
    
    long elapsed = System.currentTimeMillis() - start;
    
    System.out.println("checkPalindrome: time elapsed: " + elapsed + " milliseconds.");
    
    
    start = System.currentTimeMillis();
    
    for (int i = 0; i < 1000000; i++) {
        Main.isPalindrome(palindrome);
        Main.isPalindrome(nonPalindrome);
    }
    
    elapsed = System.currentTimeMillis() - start;
    
    System.out.println("isPalindrome: time elapsed: " + elapsed + " milliseconds.");
    
    
}

private static boolean isPalindrome(String s) {
    int i = 0;
    int j = s.length() - 1;
    
    while (i < j) {
        if (Character.isWhitespace(s.charAt(i))) {
            i++;
            continue;
        }
        
        if (Character.isWhitespace(s.charAt(j))) {
            j--;
            continue;
        }
        
        if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) {
            return false;
        } else {
            i++;
            j--;
        }
        
    }
    
    return true;
}

private static boolean checkPalindrome(String string) {
    char[] chars = string.replaceAll(" ", "").toLowerCase().toCharArray();
    for (int i = 0; i < chars.length / 2; ++i) {
        if (chars[i] != chars[chars.length - 1 - i]) {
            return false;
        }
    }
    return true;
}

}


Running on my computer produced the following result:

checkPalindrome: time elapsed: 7373 milliseconds.

isPalindrome: time elapsed: 421 milliseconds.

Code Snippets

char[] chars = string.replaceAll(" ", "").toLowerCase().toCharArray();
private static boolean isPalindrome(String s) {
    int i = 0;
    int j = s.length() - 1;
    
    while (i < j) {
        if (Character.isWhitespace(s.charAt(i))) {
            i++;
            continue;
        }
        
        if (Character.isWhitespace(s.charAt(j))) {
            j--;
            continue;
        }
        
        if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) {
            return false;
        } else {
            i++;
            j--;
        }
    }
    return true;
}
public class Main {

public static void main(String[] args) {

    String palindrome = "a b c de f g h x x xa b   a xxx     hg f e d c b  a";
    String nonPalindrome = "abcd e f g h  xxxabcxxx hgfe  d c ba";

    long start = System.currentTimeMillis();
    
    for (int i = 0; i < 1000000; i++) {
        Main.checkPalindrome(palindrome);
        Main.checkPalindrome(nonPalindrome);
    }
    
    long elapsed = System.currentTimeMillis() - start;
    
    System.out.println("checkPalindrome: time elapsed: " + elapsed + " milliseconds.");
    
    
    start = System.currentTimeMillis();
    
    for (int i = 0; i < 1000000; i++) {
        Main.isPalindrome(palindrome);
        Main.isPalindrome(nonPalindrome);
    }
    
    elapsed = System.currentTimeMillis() - start;
    
    System.out.println("isPalindrome: time elapsed: " + elapsed + " milliseconds.");
    
    
}


private static boolean isPalindrome(String s) {
    int i = 0;
    int j = s.length() - 1;
    
    while (i < j) {
        if (Character.isWhitespace(s.charAt(i))) {
            i++;
            continue;
        }
        
        if (Character.isWhitespace(s.charAt(j))) {
            j--;
            continue;
        }
        
        if (Character.toLowerCase(s.charAt(i)) != Character.toLowerCase(s.charAt(j))) {
            return false;
        } else {
            i++;
            j--;
        }
        
    }
    
    return true;
}

private static boolean checkPalindrome(String string) {
    char[] chars = string.replaceAll(" ", "").toLowerCase().toCharArray();
    for (int i = 0; i < chars.length / 2; ++i) {
        if (chars[i] != chars[chars.length - 1 - i]) {
            return false;
        }
    }
    return true;
}

}

Context

StackExchange Code Review Q#74249, answer score: 9

Revisions (0)

No revisions yet.