导致此StringIndexOutofBounds异常的原因是什么?

时间:2016-01-15 02:36:23

标签: java string indexing replaceall

我有这个代码在下面找到一个回文;我需要能够从用户输入字符串中删除所有数字,空格和标点符号,所以我一直在使用replaceAll。当我的代码中只有String input = str.toLowerCase();String newInput = input.replaceAll("[0-9]+", "");时,没有问题。它删除了数字并继续。但是,当我尝试添加标点符号或空格时,我得到一个StringIndexOutOfBoundsException。

示例:我输入了Anna.55

所有replaceAll语句System.out.println(newestInput);下面的行将打印出anna,但在到达while循环时会立即抛出错误,并指出问题与索引为6。

根据我的理解(我还在学习Java并且不熟悉replaceAll)删除带有replaceAll("\\s", "")的空格会删除前面replaceAll语句留下的空格,因此会有没有索引6(甚至4)。当指数不再存在时,如何在索引为6时出现错误?

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();
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您正在使用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) {

这意味着String不再是原始长度,在您的示例中,1字符更短

而是计算newestInput的长度

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

答案 1 :(得分:2)

首先要做的两件事:

我认为

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

应该是

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

并且应该在删除令牌之后计算正确,而不是之前,就像这样:

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;

否则right可能会大于newestInput的长度,您将获得java.lang.StringIndexOutOfBoundsException

答案 2 :(得分:0)

实际上,测试一个字符串是否为回文的更简单方法是向前和向后是否相同。