从JavaDoc
的java.lang 类的StringIndexOutOfBoundsException
按字符串方法抛出以指示索引为负数 或大于字符串的大小。对于某些方法(如 charAt方法),当索引等于 到字符串的大小时,也会抛出此异常。
您超出了字符串的长度。
此外,我认为你的逻辑有一些错误(见下文)。
你真正正在尝试做的是这样的:
while ((k < s.length()) && (j < s.length())) { // While no String goes out of Bounds
if (s.charAt(j) != s.charAt(k)) { // If we get a different character
break; // Get out of the loop
} else {
j++; // Advance one position
k++;
}
}
什么,你这样做是这样的:
if (s.charAt(j) == s.charAt(k)) { // If the characters are equal
while ((s.charAt(j) == s.charAt(k)) // While the characters are equal
&& (k < s.length()) && (j < s.length())) { // And the position is smaller than the length
j++;
k++;
}
count += j;
}
的如果是多余的,因为你的同时再检查一下也无妨,和计数将增加零。
但更重要的是,在终止条件下,您检查s.charAt(j)
是否发生在检查j < s.length()
之前。因此,你在第一种情况下例外,你看如果j是大
另外之前,因为表达式是Java的计算由左到右,你可以改变你的循环是这样的:
while ((k < s.length()) && (j < s.length()) && (s.charAt(j) == s.charAt(k))) {
j++;
k++;
}
现在你不会得到一个异常,因为如果前两项是错误的(从左边),那么右边的另两项将不会被评估(至少在我的JVM中)
输出:
run:
2
ababaa
aa
11
3
希望有所帮助。
PS:我也改了行
int t = se.nextInt();
到
int t = se.nextInt();se.nextLine();
所以你解析换行给出的数字后。
澄清
1)为什么se.nextLine()
你有
int t = se.nextInt();
比方说,用户输入23
并按下输入,这意味着InputSream whill从键盘23\n
读取。 23
是用户输入的号码,\n
是换行字符。使用换行符字符,以便计算机可以知道一行结束并且下一行开始,并且当用户按下输入时它会自动插入。更多的信息在这里:How do I get a platform-dependent new line character?
当你打电话给nextInt()
,你只能读取输入的号码,但你没有阅读\n
字符。因此,下次您拨打readLine()
时,您会看到从您输入号码(并按下回车)后遗留下来的\n
。这是什么原因你改变了上面的命令
int t = se.nextInt();se.nextLine();
现在你看的额外\n
性格,和nextLine()
下一个电话,当你读取用户输入的字符串会发生,将正确返回字符串。
2)为什么磨片循环改为((k < s.length()) && (j < s.length()) && (s.charAt(j) == s.charAt(k))
你有这个
((s.charAt(j)==s.charAt(k)) && (k<s.length()) && (j<s.length()))
这引起了的StringIndexOutOfBoundsException。这是为什么:
在Java中,表达式是从左到右计算的。这意味着,在每次迭代时,JVM将首先检查(s.charAt(j)==s.charAt(k))
。如果术语是true,那么它将评估术语(k<s.length())
,如果这也是true,它将评估(j<s.length())
。如果所有这些条款都是true,程序将进入循环。另一方面,如果第一项(即,第一项)(即,第一项(即,第一项))小于或等于第一项(即,(s.charAt(j)==s.charAt(k))
)是false,那么整个表达式是false(因为我们有和和算子),并且没有必要计算其余的项。
现在,为什么会造成异常?看看最后一次迭代会发生什么。此时,变量j
(或等效为k
)的值将等于字符串s
的长度。当JVM尝试评估终止条件时,它将首先评估术语(s.charAt(j)==s.charAt(k))
。由于j
等于s
的长度,因此调用charAt()
将抛出StringIndexOutOfBoundsException,因为调用将尝试获取以外的字符的字符串。请记住,字符串中的索引是从0
到length() - 1
。这是你的例外。
但是,如果你改变了终止条件,以
((k < s.length()) && (j < s.length()) && (s.charAt(j) == s.charAt(k)))
你将避免的StringIndexOutOfBoundsException。这是为什么。这次,条款(k < s.length())
和(j < s.length())
在之前被评估为,调用charAt()
。因此,当我们到达字符串的末尾时,两个第一项中至少有一个是false
,并且不需要评估表达式的其余部分。因此,在最后一次迭代中,根本不调用方法charAt
,所以我们没有得到异常。
我希望这可以澄清一些情况。
什么问题?这个计划的工作是什么?什么是投入,产出和预期产出? – leemes 2013-02-09 13:08:19
其实这是来自面试街道的问题https://www.hackerrank.com/challenges/string-similarity – saimadan 2013-02-09 13:13:26
@saimadan检查我的答案。如果你的逻辑其余部分是正确的,那么你完成了例外.. – Arpit 2013-02-09 13:14:54