2013-07-03 142 views
2

我创建了类Word。 Word有一个构造函数,它接受一个字符串参数和一个方法getSubstrings,它返回一个包含所有字的子串的字符串,按照长度排序。查找字符串的所有子字符串 - StringIndexOutOfBoundsException

例如,如果用户提供了输入“朗姆酒”,则该方法返回一个 串,将打印这样的:

r 
u 
m 
ru 
um 
rum 

我要连接的子串在一个字符串,将它们与分离换行符(“\ n”)。然后返回字符串。

代码:

public class Word { 
    String word; 

    public Word(String word) { 
     this.word = word; 
    } 
    /** 
    * Gets all the substrings of this Word. 
    * @return all substrings of this Word separated by newline 
    */ 

    public String getSubstrings() 
    { 
     String str = ""; 
     int i, j; 
     for (i = 0; i < word.length(); i++) { 
      for (j = 0; j < word.length(); j++) { 
       str = word.substring(i, i + j); 
       str += "\n"; 
      } 
     } 
     return str; 
    } 

但它抛出异常:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1 
    at java.lang.String.substring(String.java:1911) 

我停留在这一点上。也许,根据此方法签名public String getSubstrings(),您还有其他建议。
如何解决这个问题?异常的

+0

次,然后考虑使用String构造函数以及'substring()'方法,就像你的情况一样,'str = new String(word.substring(i,i + j));'。否则,它可能会在某个时间导致内存泄漏(是的,但它与具体问题无关)。 – Lion

回答

6

分析:

Java7 Docs of StringIndexOutOfBoundsException

public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException 

由String方法抛出,表明索引或者为负,或者超出字符串的尺寸越大。

Java 7 Docs of substring

public String substring(int beginIndex,int endIndex) 

返回一个新字符串,它是此字符串的一个子。子字符串从指定的beginIndex开始,并扩展到索引endIndex - 1处的字符。因此,子字符串的长度是endIndex-beginIndex。

我想这:长度的字符串是endIndex的-的beginIndex进入String index out of range: -1。我已经测试了多个案例,并坚持我的假设,但非常感谢任何其他证明。

为-1:"rum".substring(2,1);会给你的StringIndexOutOfBoundsExceptionString index out of range: -1

Parameters: 
    beginIndex - the beginning index, inclusive. 
    endIndex - the ending index, exclusive. 

原因:

在给定的代码片段,substring正在努力获取具有比总长度endIndex多串的字符串(i+j将超过字符串的总长度):

str = word.substring(i, i + j); 

考虑的情况下当i = 2且j = 2 “朗姆酒” 字

然后str=word.substring(2, 4); 将是不可能的

解类似于问题给出的代码片断:

这应该解决问题:

public String getSubstrings() 
    { 
     String str="",substr = ""; 
     for (int i = 0; i < word.length(); i++) { 
      for (int j = 0; i+j <= word.length(); j++) { //added i+j and equal to comparison 
       substr = word.substring(j, i + j); //changed word.substring(i, i + j) to word.substring(j, i + j) 
       if("".equals(substr))continue; //removing empty substrings 
       str += substr; //added concatenation + operation 
       str += "\n"; 
      } 
     } 
     return str+word; 
    } 

测试案例:

word="rum",这会给输出:

r 
u 
m 
ru 
um 
rum 
+0

这是失败 - 任何输出。 –

+2

这是因为'str'会在'='的内部循环中被覆盖。将其更改为'+ =' –

+0

感谢@HunterMcMillen :) – ritesh

4

你的逻辑似乎令人费解,异常的来源:

str = word.substring(i, i + j); 

考虑你ij都等于word.length()-1,那么substring()会失败。

你可以简单地做:

public String getSubstrings(String word){ 
    StringBuilder sub= new StringBuilder(); 
    for(int i = 0 ; i < word.length() ; i++) 
    { 
     for(int j = 1 ; j <= word.length() - i ; j++) 
     { 
     sub .append(word.substring(i, i+j)).append("\n"); 
     } 
    } 
    return sub.toString(); 
} 

注:考虑使用StringBuilder代替String,如果你会做大量的串联对String

+0

您的建议失败 –

+0

@nazar_art您能与我分享测试结果吗? – NINCOMPOOP

+0

你不能改变'public String getSubstrings()'方法的签名' –

1

我意识到我对这个派对有点迟到,我是一个非常新的程序员,我自己 - 但是我昨天在尝试写类似的方法时遇到了同样的错误。

对我来说,它帮助将嵌套for循环的计数器变量重命名为描述他们正在追踪的内容的名称。对于外部循环,我使用了int subLength,对于内部循环,我使用了int position(起始位置)。我确信还有其他方法可以做到这一点,但我对我的解决方案感到满意。下面是一些伪代码,我希望能帮助别人谁看起来这个问题了:如果你使用`子()`方法在循环中具有迭代次数,即该方法可能会被调用很多

 for each possible substring length 1 up to and including the original word length: 
      generate substrings starting at the 0th position, and then starting at each 
      proceeding letter up to but not including (word.length() - (subLength - 1)) 
相关问题