StringIndexOutOfBounds when removing adjacent duplicate letters

我怕爱的太早我们不能终老 提交于 2020-01-17 07:53:49

问题


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 if statements do the same thing (return s;) and can be combined into one. Some of the conditions are redundant and can be eliminated.
  • The third if statement should immediately return instead of continuing into the fourth if statement (or you can instead change the fourth if statement into an else), because removedAdjDuplicates can return an empty String making s a length-one String when the fourth if is expecting at least a length-two String.
  • The fourth if can be eliminated because if (s.charAt(0) != s.charAt(1)) failed in the third if, 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!