为什么我的程序抛出 StringIndexOutOfBounds 异常?
Why is my program throwing a StringIndexOutOfBounds exception?
我正在写一个程序来计算:
1^1 + 2^2 + 3^3 + ... + 1000^1000 = ?
一旦计算出来,我想删除答案中除最后十位以外的所有数字,然后在屏幕上打印最后十位。要删除所有其他数字,我正在使用 StringBuilder.deleteCharAt()
方法,但是,这给我带来了一些问题。我在下面提供了我的代码:
import java.math.BigInteger;
public class problemFourtyEight {
public static void main(String [] args) {
BigInteger answer = new BigInteger(""+0);
for(int i = 0; i <= 1000; i++) {
BigInteger temp = new BigInteger(""+i);
temp = temp.pow(i);
answer = answer.add(temp);
}
System.out.println(answer.toString().length());
StringBuilder sb = new StringBuilder((answer.toString()));
for(int k = 0; k <= (answer.toString().length() - 10); k++) {
sb.deleteCharAt(k); //Line 13 is here.
}
String finalAnswer = sb.toString();
System.out.println(finalAnswer);
}
}
抛出的异常是:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1501
at java.lang.AbstractStringBuilder.deleteCharAt(AbstractStringBuilder.java:797)
at java.lang.StringBuilder.deleteCharAt(StringBuilder.java:253)
at problemFourtyEight.main(problemFourtyEight.java:13)
打印出答案的长度(在删除任何字符之前),它告诉我数字的长度是 3001,所以我不明白为什么 String index
1,501 说是 OutOfBounds
.
当您删除第 i 个字符时,第 i+1 个字符将成为新的第 i 个字符。因此,您的外观应该始终删除第一个字符:
for(int k = 0; k <= (answer.toString().length() - 10); k++) {
sb.deleteCharAt(0);
}
例如:
StringBuilder sb = new StringBuilder("abcdef");
sb.deleteCharAt(0);
sb.deleteCharAt(1);
sb.deleteCharAt(2);
sb.deleteCharAt(3); // throws java.lang.StringIndexOutOfBoundsException: String index out of range: 3
System.out.println(sb.toString());
sb = new StringBuilder("abcdef");
sb.deleteCharAt(0);
sb.deleteCharAt(0);
sb.deleteCharAt(0);
sb.deleteCharAt(0);
System.out.println(sb.toString()); // prints "ef"
你的错误是这段代码:
StringBuilder sb = new StringBuilder((answer.toString()));
for(int k = 0; k <= (answer.toString().length() - 10); k++) {
sb.deleteCharAt(k); //Line 13 is here.
}
由于字符串生成器的可变性,使字符串更短。
你想要:
System.out.println(answer.substring(answer.length()-10))
这也有速度的优势,如果这对你很重要的话。
我认为这是因为每次从字符串中删除一个字符时,字符串缓冲区都会调整大小并且您的字符串会变短,因此从 3001 中删除 1500 个字符后,您的字符串缓冲区将存储从 0 到 1500 的字符和索引 1501超出范围。
您可以使用 substring 打印最后 10 位数字。
如果您检查 StringBuilder
对象的长度,此代码可能(有些)有效,但您检查原始字符串的长度,但从 StringBuilder
中删除字符。每次删除时 StringBuilder
都会变短,因此最终 k
索引超出了 sb
.
的范围
StringBuilder sb = new StringBuilder((answer.toString()));
for(int k = 0; k <= (sb.length() - 10); k++) { // <-- make sure to test the length of the thing you are mutating
sb.deleteCharAt(0); // Delete first character of remaining sb
}
但是,是的,substring()
应该更 在这里。
我正在写一个程序来计算:
1^1 + 2^2 + 3^3 + ... + 1000^1000 = ?
一旦计算出来,我想删除答案中除最后十位以外的所有数字,然后在屏幕上打印最后十位。要删除所有其他数字,我正在使用 StringBuilder.deleteCharAt()
方法,但是,这给我带来了一些问题。我在下面提供了我的代码:
import java.math.BigInteger;
public class problemFourtyEight {
public static void main(String [] args) {
BigInteger answer = new BigInteger(""+0);
for(int i = 0; i <= 1000; i++) {
BigInteger temp = new BigInteger(""+i);
temp = temp.pow(i);
answer = answer.add(temp);
}
System.out.println(answer.toString().length());
StringBuilder sb = new StringBuilder((answer.toString()));
for(int k = 0; k <= (answer.toString().length() - 10); k++) {
sb.deleteCharAt(k); //Line 13 is here.
}
String finalAnswer = sb.toString();
System.out.println(finalAnswer);
}
}
抛出的异常是:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1501
at java.lang.AbstractStringBuilder.deleteCharAt(AbstractStringBuilder.java:797)
at java.lang.StringBuilder.deleteCharAt(StringBuilder.java:253)
at problemFourtyEight.main(problemFourtyEight.java:13)
打印出答案的长度(在删除任何字符之前),它告诉我数字的长度是 3001,所以我不明白为什么 String index
1,501 说是 OutOfBounds
.
当您删除第 i 个字符时,第 i+1 个字符将成为新的第 i 个字符。因此,您的外观应该始终删除第一个字符:
for(int k = 0; k <= (answer.toString().length() - 10); k++) {
sb.deleteCharAt(0);
}
例如:
StringBuilder sb = new StringBuilder("abcdef");
sb.deleteCharAt(0);
sb.deleteCharAt(1);
sb.deleteCharAt(2);
sb.deleteCharAt(3); // throws java.lang.StringIndexOutOfBoundsException: String index out of range: 3
System.out.println(sb.toString());
sb = new StringBuilder("abcdef");
sb.deleteCharAt(0);
sb.deleteCharAt(0);
sb.deleteCharAt(0);
sb.deleteCharAt(0);
System.out.println(sb.toString()); // prints "ef"
你的错误是这段代码:
StringBuilder sb = new StringBuilder((answer.toString()));
for(int k = 0; k <= (answer.toString().length() - 10); k++) {
sb.deleteCharAt(k); //Line 13 is here.
}
由于字符串生成器的可变性,使字符串更短。 你想要:
System.out.println(answer.substring(answer.length()-10))
这也有速度的优势,如果这对你很重要的话。
我认为这是因为每次从字符串中删除一个字符时,字符串缓冲区都会调整大小并且您的字符串会变短,因此从 3001 中删除 1500 个字符后,您的字符串缓冲区将存储从 0 到 1500 的字符和索引 1501超出范围。
您可以使用 substring 打印最后 10 位数字。
如果您检查 StringBuilder
对象的长度,此代码可能(有些)有效,但您检查原始字符串的长度,但从 StringBuilder
中删除字符。每次删除时 StringBuilder
都会变短,因此最终 k
索引超出了 sb
.
StringBuilder sb = new StringBuilder((answer.toString()));
for(int k = 0; k <= (sb.length() - 10); k++) { // <-- make sure to test the length of the thing you are mutating
sb.deleteCharAt(0); // Delete first character of remaining sb
}
但是,是的,substring()
应该更 在这里。