问题
Here is my code:
public static String removeAdjDuplicates(String s) {
if(s == "" || s == null || s.isEmpty())
return s;
if(s.length() < 2)
return s;
if(s.charAt(0) != s.charAt(1))
s = s.charAt(0) + removeAdjDuplicates(s.substring(1));
if(s.charAt(0) == s.charAt(1)) //line 37
return removeAdjDuplicates(s.substring(2));
return s;
}
With the input string "ull", I get the following error:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(String.java:658)
at GFG.removeAdjDuplicates(File.java:37)
at GFG.main(File.java:16)
I read and tried answers given to similar questions, but I'm not sure what is wrong.
回答1:
As you Try to pass this string "ull" to the method the last letter in the String should be the letter "u" because you use this
if(s.charAt(0) != s.charAt(1))
s = s.charAt(0) + removeAdjDuplicates(s.substring(1));
as you dont return the String back like the other conditions in the method it will continue to the next condition at line 37 and u have only one letter while the condition checking the first and the second characters ... there is no second letter so you get this error .. so the solution is to return s like this
if(s.charAt(0) != s.charAt(1)){
s = s.charAt(0) + removeAdjDuplicates(s.substring(1));
return s;
}
回答2:
Judging from the exception that you get, removeAdjDuplicates returns an empty string, invalidating all indexes past zero.
Although your code performs length checking at the top, it also performs this assignment when the two initial characters are different:
s = s.charAt(0) + removeAdjDuplicates(s.substring(1));
This means that s can become a one-character string if removeAdjDuplicates returns an empty string.
回答3:
I think the source of the error is sufficiently explained by @dasblinkenlight's answer.
Although not clearly stated in the question, it looks like you're trying to remove adjacent duplicate letters recursively (one of your comments mentions that you would expect output s for input geegs).
Here's an alternative way to do it:
while(!s.equals(s = s.replaceAll("(.)\\1", "")));
It uses a regular expression to match and remove duplicate characters, and the while loop keeps executing this until the string is no longer being modified by the operation.
回答4:
You should simplify your code:
public static String removeAdjDuplicates(String s) {
if (s == null || s.length() < 2)
return s;
if (s.charAt(0) != s.charAt(1))
return s.charAt(0) + removeAdjDuplicates(s.substring(1));
return removeAdjDuplicates(s.substring(2));
}
Changes
- The first two
ifstatements do the same thing (return s;) and can be combined into one. Some of the conditions are redundant and can be eliminated. - The third
ifstatement should immediatelyreturninstead of continuing into the fourth if statement (or you can instead change the fourthifstatement into anelse), becauseremovedAdjDuplicatescan return an emptyStringmakingsa length-oneStringwhen the fourthifis expecting at least a length-twoString. - The fourth
ifcan be eliminated because if(s.charAt(0) != s.charAt(1))failed in the thirdif, then the only alternative is that(s.charAt(0) == s.charAt(1)), so the check for that isn't necessary.
来源:https://stackoverflow.com/questions/41477037/stringindexoutofbounds-when-removing-adjacent-duplicate-letters