2016-01-15 86 views
-2

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

例:I输入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(); 
     } 
    } 
} 
+0

首先''input.replaceAll(“\\ W”,“”)''不应该在这里使用'newInput'吗?第二:是否认为计算'right'是一个好主意,_before_你减少你的源字符串的大小? – Tom

+0

'如果在索引为6时出现错误,它不再存在吗?'这不是回答你的问题吗?您需要包含堆栈跟踪的相关部分,以便人们更好地帮助您。 – John3136

回答

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代替

的长度210
right = newestInput.length() - 1; 
System.out.println(newestInput); 
while (newestInput.charAt(left) == newestInput.charAt(right) && left < right) { 
+0

*“它缩短了1个字符”* ..这就是有趣的部分,它应该缩短3个字符:D。但解决方案很简单,所以它不再有趣。 – Tom

+1

input ='Anna.55' output ='anna55'; OP在'String'的错误实例上使用'repalceAll'的事实,考虑到问题的性质,我想他们会得到1“免调试卡”) – MadProgrammer

+0

这是我的疏忽,对不起。我确信问题在于我如何使用'replaceAll'错误,我没有检查我的语句的顺序/位置。谢谢! –

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

0

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

相关问题