【问题标题】:how do i convert this for loop to the correct while loop? [closed]如何将此 for 循环转换为正确的 while 循环? [关闭]
【发布时间】:2025-12-01 08:20:02
【问题描述】:

我在下面输入的这段代码是原来的 for 循环

  String[][] wordData = {{"study", "consider", "examine", "learn"}, {"ponder", "read", "think", "cogigate"}};

int characterCount = 0;
for(String[] stringRow : wordData) {
    for(String s : stringRow) {
        characterCount += s.length();
    }
}
System.out.println(characterCount);

这是我对 while 循环的尝试

int i = 0, j = 0;
while(i<wordData.length) {
    j=0;
    while(j<wordData[i].length) {
        characterCount += wordData[j].length;
        System.out.print(characterCount);
        j++;
    }
    i++;
}

【问题讨论】:

  • characterCount += wordData[j].length; 应该是characterCount += wordData[i][j].length;

标签: java for-loop while-loop


【解决方案1】:

您必须在每个步骤中计算word[i][j] 的长度。实际上 word[j] 是一个数组。

word[0] // {"study", "consider", "examine", "learn"}
word[1] // {"ponder", "read", "think", "cogigate"}

while实现这段代码的正确方法是这样。

int characterCount = 0;
int i = 0, j = 0;
while (i < wordData.length) {
    j = 0;
    while (j < wordData[i].length) {
        characterCount += (wordData[i][j]).length();
        j++;
    }
    i++;
}
System.out.println(characterCount);

只是一个小东西,你必须在最后打印结果,而不是在循环中。

【讨论】:

    【解决方案2】:
    String[][] wordData = { {"study", "consider", "examine", "learn"}, {"ponder", "read", "think", "cogigate"}};
    int characterCount = 0;
    int i = 0;
    while(i<wordData.length){
        int j = 0;
        while(j<wordData[i].length){
           characterCount += wordData[i][j].length();
           j++;
        }
        i++;
    }
    
    System.out.println(characterCount);
    

    【讨论】:

      【解决方案3】:

      for 转换为while

      您只需了解for 循环的工作原理,即可将任何for 循环转换为while 循环。这是一个简单的例子:

      for (A; B; C) {
          D;
      }
      

      等价于

      A;
      while (B) {
          D;
          C;
      }
      

      但是,在您的具体情况下,您使用的不是传统的 for 循环,而是增强的 for 循环。其中,对于collections(任何Iterable)等同于使用Iterator

      // elements being a collection like List<E>
      for (E element : elements) {
          ...
      }
      

      一样
      Iterator<E> elementIter = elements.iterator();
      while (elementIter.hasNext()) {
          E element = elementIter.next();
          ...
      }
      

      但是,在您的特定情况下,您在数组上使用了增强的 for 循环。将其转换为传统的基于索引的 for 循环。所以

      // elements being an array like E[]
      for (E element : elements) {
          ...
      }
      

      等价于

      for (int i = 0; i < elements.length; i++) {
          E element = elements[i];
          ...
      }
      

      我们可以轻松地将其转换为while 循环,如前所示:

      int i = 0;
      while (i < elements.length) {
          E element = elements[i];
          ...
          i++;
      }
      

      您的代码

      话虽如此,现在让我们看看您的代码。在我们开始更详细地考虑您的代码之前,让我们盲目地应用上述转换:

      第一步,将增强的for循环转换为传统的for循环:

      String[][] wordData = {
          {"study", "consider", "examine", "learn"},
          {"ponder", "read", "think", "cogigate"}
      };
      
      int characterCount = 0;
      for (int i = 0; i < wordData.length; i++) {
          String[] stringRow = wordData[i];
          for (int j = 0; j < stringRow.length; i++) {
              String s = stringRow[j];
              characterCount += s.length();
          }
      }
      System.out.println(characterCount);
      

      现在 while 循环:

      String[][] wordData = {
          {"study", "consider", "examine", "learn"},
          {"ponder", "read", "think", "cogigate"}
      };
      
      int characterCount = 0;
      int i = 0;
      while (i < wordData.length) {
          String[] stringRow = wordData[i];
          int j = 0;
          while (j < stringRow.length) {
              String s = stringRow[j];
              characterCount += s.length();
              j++;
          }
          i++;
      }
      System.out.println(characterCount);
      

      如您所见,这相当容易。


      在我们讨论的同时,让我也向您展示一种如何使用流来解决您的任务的方法,因为它非常简短和优雅:

      int characterCount = Stream.of(wordData) // Stream<String[]>
          .flatMap(Stream::of)                 // Stream<String>
          .mapToInt(String::length)            // IntStream
          .sum();
      

      Unicode

      关于 Unicode 缺陷的最后一点说明。您正在使用String::length 测量characterCount。这可能适用于您感兴趣的所有情况。但是,对于 Unicode 表中 更高 的符号,它将输出不正确的值。

      例如字符串:

      ??
      

      长度为4。我不是在开玩笑,"??".length() 返回 4 而不是 2

      这是因为像?? 这样的符号实际上需要2 个chars 来表示。 Unicode 是一种可变字节长度编码,因此并非所有符号都适合 Java char 使用的 16 位。因此,如果您希望您的代码也适用于此类符号,则必须使用 code points 而不是简单的普通 string length

      幸运的是,在 Java 中执行此操作仍然相当简单。以下是也适用于此类输入的流版本:

      int characterCount = Stream.of(wordData)
          .flatMap(Stream::of)
          .mapToInt(s -> s.codePointCount(0, s.length())
          .sum();
      

      【讨论】: