我正在嘗試將一個字串與其自身連接并從結果字串中洗掉所有大寫字母。
這是我的代碼:
public String removeCapitals(String A) {
StringBuilder B = new StringBuilder(A A);
int n = B.length();
for(int i=0; i<n; i ){
if(B.charAt(i)>='A' && B.charAt(i)<='Z'){
B.deleteCharAt(i);
}
}
return B.toString();
}
我收到例外說:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
at java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:237)
at java.lang.StringBuilder.charAt(StringBuilder.java:76)
at Solution.removeCapitals(Solution.java:10)
at Main.main(Main.java:190)
有人可以幫我理解這個問題。
uj5u.com熱心網友回復:
如果至少有一次洗掉成功,在某些時候您的代碼將嘗試訪問超過StringBuilder.
發生這種情況是因為變數n保持不變。您應該將條件更改為系結到當前大小StringBuilder并在每次洗掉時減少索引,或向后迭代(如另一個答案所示)。
條件B.charAt(i)>='A' && B.charAt(i)<='Z'也可以替換為:
Character.isUpperCase(b.charAt(i))
哪個更具描述性。
這就是它的樣子:
public static String removeCapitals(String a) {
StringBuilder b = new StringBuilder(a a);
for (int i = 0; i < b.length(); i ) {
if (Character.isUpperCase(b.charAt(i))) {
b.deleteCharAt(i); // which can be combined with the next line `b.deleteCharAt(i--);` - previous value of `i` would be used in the call `deleteCharAt()` and variable `i` will hold a value decremented by 1
i--;
}
}
return b.toString();
}
方法deleteCharAt()以線性時間運行,因為它移動了底層陣列位元組中的所有后續字符。每個大寫字母都會觸發這些變化,在最壞的情況下,它會導致二次總時間復雜度O(n ^ 2)。
在不使用回圈和StringBuilder. 此代碼將在線性時間O(n)中運行。
public static String removeCapitals(String a) {
return a.replaceAll("\\p{Upper}", "").repeat(2);
}
uj5u.com熱心網友回復:
當您洗掉一個字符時,您會更改 StringBuilder 的長度。但n還是有原來的長度。所以你最終會超過StringBuilder. 所以從頭開始,向后移動。這樣,任何洗掉都將after(基于相對索引)下一個位置,因此索引將在修改后的StringBuilder大小范圍內。此外,從末尾洗掉更有效,因為在 StringBuilder 中要做的復制更少。
public String removeCapitals(String A) {
StringBuilder B = new StringBuilder(A A);
int n = B.length();
for(int i=n-1; i>=0; i--){
if(B.charAt(i)>='A' && B.charAt(i)<='Z'){
B.deleteCharAt(i);
}
}
return B.toString();
}
uj5u.com熱心網友回復:
如果只是從字串中洗掉大寫字符。替代解決方案只是創建另一種方法replaceAll() regex
private static String removeCapitals(String A){
if (!A.isEmpty() && !A.equals("")) {
String B = A A;
String newStr = B.replaceAll("([A-Z])", "");
return newStr;
} else {
return null;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/488634.html
上一篇:從名稱串列中獲取唯一名稱
