-2

I have this code to find a palindrome below; I need to be able to remove all numbers, spaces, and punctuation from the user input String, so I've been using replaceAll. When I only had String input = str.toLowerCase(); and String newInput = input.replaceAll("[0-9]+", ""); in my code, there was no problem. It removes the numbers and continues. However when I try to add punctuation or a space, I get a StringIndexOutOfBoundsException.

Example: I input Anna.55

The line underneath all of the replaceAll statements, System.out.println(newestInput);, will print out anna but immediately throws the error when reaching the while loop and states that the problem is with the index of 6.

From my understanding (I am still learning Java and am unfamiliar with replaceAll) removing the spaces with replaceAll("\\s", "") would remove the spaces left by the previous replaceAll statements and thus there would be no index 6 (or even 4). How is there an error at index of 6 when it no longer exists?

import java.util.Scanner;

public class PalindromeTester {
    public static void main (String[] args) {
        String str;
        String another = "y";
        int left;
        int right;
        Scanner scan = new Scanner (System.in);
        while (another.equalsIgnoreCase("y")) {
            System.out.println("Enter a potential palindrome:");
            str = scan.nextLine();  
            left = 0;
            right = str.length() - 1;           
            String input = str.toLowerCase(); 
            String newInput = input.replaceAll("[0-9]+", "");
            String newerInput = input.replaceAll("\\W", "");
            String newestInput = newerInput.replaceAll("\\s", "");           
            System.out.println(newestInput);
            while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) {
                left++;
                right--;
            }
             System.out.println();
            if (left < right)
                System.out.println("That string is not a palindrome.");
            else 
                System.out.println("That string is a palindrome.");
            System.out.println();
            System.out.print ("Test another palindrome (y/n)? ");
            another = scan.nextLine();
        }
    }
}
John S.
  • 626
  • 1
  • 4
  • 16
Sarah Diri
  • 97
  • 1
  • 9
  • First of all `input.replaceAll("\\W", "")` shouldn't you use `newInput` here? Second: do think it is a good idea to calculate `right`, _before_ you decrease the size of your source String? – Tom Jan 15 '16 at 02:38
  • `How is there an error at index of 6 when it no longer exists?` Doesn't that kind of answer your question? You need to include the relevant parts of the stack trace to give people a better chance of helping you. – John3136 Jan 15 '16 at 02:39

3 Answers3

2

You're using right = str.length() - 1; to determine the length of the input, but you modify what was input after it (and what you compare)...

String input = str.toLowerCase();
String newInput = input.replaceAll("[0-9]+", "");
String newerInput = input.replaceAll("\\W", "");
String newestInput = newerInput.replaceAll("\\s", "");

System.out.println(newestInput);
while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) {

Which means the String is no longer the original length, in your example, it's 1 character shorter

Instead, calculate the length of the newestInput instead

right = newestInput.length() - 1;
System.out.println(newestInput);
while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) {
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • *"it's 1 character shorter"* .. thats the interesting part, it should be 3 characters shorter :D. But the solution to that is quite easy, so it isn't interesting anymore. – Tom Jan 15 '16 at 02:44
  • 1
    input = `Anna.55` output = `anna55`; the fact the OP is using `repalceAll` on the wrong instance of the `String`, well, given the nature of the question, I figured they'd get 1 "get debugging free" card ;) – MadProgrammer Jan 15 '16 at 02:46
  • It was my oversight, sorry. I was convinced the problem was with how I was using `replaceAll` wrong that I didn't check the order/placement of my statements. Thank you! – Sarah Diri Jan 15 '16 at 02:52
  • @SarahDiri Use you're older code to get familiar with a code debugger. There you can see that each variable "contains". It is very useful to know how a debugger works, to solve problems like this. – Tom Jan 15 '16 at 02:57
2

Two things first:

I think

input.replaceAll("\\W", "");

should be

newInput.replaceAll("\\W", "");

And right should be calculated after the tokens are removed and not before, like so:

left = 0;
String input = str.toLowerCase(); 
String newInput = input.replaceAll("[0-9]+", "");
String newerInput = newInput.replaceAll("\\W", "");
String newestInput = newerInput.replaceAll("\\s", "");
right = newestInput.length() - 1;

Otherwise right can be larger than the length of newestInput and you'll get a java.lang.StringIndexOutOfBoundsException.

Tom
  • 16,842
  • 17
  • 45
  • 54
0

Actually, an easier way to test if a string is a palindrome, is if it is the same backwards and forwards.

John S.
  • 626
  • 1
  • 4
  • 16