【问题标题】:String index out of range: 22 exception Java字符串索引超出范围:22 异常 Java
【发布时间】:2021-08-12 18:28:13
【问题描述】:

我不断得到 String index out of bound: 22 异常。谁能告诉我我做错了什么?代码如下:

class Troll {
    private static final char[] VOWELS = {'a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U'};

    public static String disemvowel(String str) {
        int lengthStr = str.length();
        int lengthVOWELS = VOWELS.length;

        for (int i = 0; i < lengthStr; ++i)
            for (char vowel : VOWELS)
                if (str.charAt(i) == vowel)
                    str = removeChar(str, i);

        return str;
    }

    private static String removeChar(String str, int index) {
        return str.substring(0, index) + str.substring(index + 1);
    }
}

我在这里要做的是编写一个函数,该函数接受一个字符串并返回一个删除所有元音的新字符串。

【问题讨论】:

    标签: java string exception indexoutofboundsexception


    【解决方案1】:
        public static String disemvowel(String str) {
            return str.replaceAll("[aeiou]", "");
        }
    

    是你需要的。如果您还想要大写字母,请使用 "[aeiouAEIOU]" 然后。这将使生成的字符串一次通过原始字符串。

    【讨论】:

      【解决方案2】:

      当你缩短一个字符串时,你会减少它的长度。但是您正在存储初始字符串长度,并将其用作循环绑定。

      i &lt; lengthStr 更改为i &lt; str.length()


      这解决了部分问题,即IndexOfOfBoundsException。另一个问题是,在删除了一个字符后,您还需要确保完全检查下一个字符。

      考虑字符串aa

      • 您会在位置 0 找到 a,然后将其删除。
      • 下一个a现在位于位置0;你会跳过检查它是否是元音
      • 接下来您将移动到检查位置 1。

      如果您按检查顺序对包含的元音进行字符串处理(例如aeiou),它会起作用,但一般不会。

      删除一个字符后,您需要停止循环遍历其他元音,然后递减 i,以确保您检查删除后紧跟的字符:

          for (int i = 0; i < lengthStr; ++i) {
              for (char vowel : VOWELS) {
                  if (str.charAt(i) == vowel) {
                      str = removeChar(str, i);
                      // Decrement i, so it gets incremented back to the
                      // same value on the next iteration of the outer loop.
                      --i;
                      break;  // Break out of vowels loop.
                  }
              }
          }
      

      但是,这是解决问题的一种非常低效的方法:每次删除一个元音时,都会重建字符串的其余部分,包括随后要删除的所有元音。

      如果你想在没有正则表达式的情况下这样做,最好的方法是创建一个StringBuilder,并且只添加非元音:

      StringBuilder sb = new StringBuilder(lengthStr);
      for (int i = 0; i < lengthStr; ++i) {
        char c = str.charAt(i);
        if (!isVowel(c) {
          sb.append(c);
        }
      }
      str = sb.toString();
      

      其中isVowel 是返回给定char 是否为元音的方法,例如

      boolean isVowel(char c) {
        return "aAeEiIoOuU".indexOf(c) >= 0;
      }
      

      【讨论】:

      • 在阅读您答案的第二部分之前,我按照您在此处所说的重新组织了代码,只是我使用了 i = 0 而不是 --i。但是我现在看到没有必要再次循环整个字符串。感谢您的快速回复。
      【解决方案3】:

      试试这个。

      private static final String VOWELS = "aAeEiIoOuU";
      
      public static String disemvowel(String str) {
          return Stream.of(str.split(""))
              .filter(c -> !VOWELS.contains(c))
              .collect(Collectors.joining());
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-23
        • 1970-01-01
        • 1970-01-01
        • 2015-05-26
        • 1970-01-01
        相关资源
        最近更新 更多