使用Java中的for循环使String索引超出范围

时间:2018-03-28 10:43:42

标签: java

我有一个for循环来从字符串中删除元音,但是如果字符串以元音结尾我会收到错误。如果字符串没有以元音结尾并且打印出结果就好了,它可以正常工作,但是如果它以元音结尾它将无法工作并且我得到错误。我怎么能解决这个问题?

package program5;

import java.util.Scanner;

public class Disemvoweling {
public static void main(String[] args) {
      Scanner scnr = new Scanner(System.in);

      String phrase;
      System.out.println("Welcome to the disemvoweling utility.");
      System.out.print("Enter your phrase: ");
      phrase = scnr.nextLine();       
      int inputLength = phrase.length();

      for (int i = 0; i < phrase.length(); i++) {
          if (phrase.charAt(i) == 'a') {
              phrase = phrase.replace("a","");
          }
          if (phrase.charAt(i) == 'e') {
              phrase = phrase.replace("e","");
          }
          if (phrase.charAt(i) == 'i') {
              phrase = phrase.replace("i","");
          }
          if (phrase.charAt(i) == 'o') {
              phrase = phrase.replace("o","");
          }
          if (phrase.charAt(i) == 'u') {
              phrase = phrase.replace("u","");
          }
      }
      System.out.println("The disemvolwed phrase is: " + phrase);
      int inputAfter = phrase.length();
      System.out.print("Reduced from " + inputLength + " characters to " + inputAfter + " characters. ");
      double percentage = (double) inputAfter / inputLength * 100; 
      double percentageRounded = (double) percentage % 1;
      System.out.print("Reduction rate of " + (percentage - percentageRounded) + "%");


}

}

2 个答案:

答案 0 :(得分:2)

异常由charAt函数生成:

  

抛出:   IndexOutOfBoundsException - 如果index参数为负数或不小于此字符串的长度。

问题是当你执行这段代码时:

phrase = phrase.replace("a","");

你缩短了字符串。如果这发生在字符串的最后一个字符串上,则下一个chartAt生成的索引超出范围:

 // Now phrase is shorter and i is over the lenght of the string
 if (phrase.charAt(i) == 'e') {
     phrase = phrase.replace("e","");
 }

每次执行continue时,解决方案都会replace到下一个循环。

   for (int i = 0; i < phrase.length(); i++) {
      if (phrase.charAt(i) == 'a') {
          phrase = phrase.replace("a","");
          continue;  // Continue to the next loop if a has been found
      }
      ....
  }

较短的解决方案将使用replaceAll方法,如下所示:

 phrase = phrase.replaceAll("[aeiou]","");

其中[aeiou]是匹配任何字符a, e, i, o, u

的正则表达式

答案 1 :(得分:1)

你过度思考它。您可以安全地删除for循环,只需替换字符,如下所示:

phrase = phrase.replace("a","");
phrase = phrase.replace("e","");
phrase = phrase.replace("i","");
phrase = phrase.replace("o","");
phrase = phrase.replace("u","");

或者更简洁

phrase = phrase.replace("a","")
               .replace("e","")
               .replace("i","")
               .replace("o","")
               .replace("u","");

最后,最短的解决方案:只使用带有replaceAll

的正则表达式
phrase = phrase.replaceAll("[aeiou]","");