【问题标题】:While loop not breaking when its condition isn't met不满足条件时循环不会中断
【发布时间】:2014-03-07 16:24:50
【问题描述】:

程序应该打印“数字 11 出现不止一次” 然后将 duplicateFound 设置为 true 并退出 while 循环,因为它是 true。 但它也会打印“数字 13 不止一次出现”。

为什么会发生这种情况以及如何中断 while 循环,以便在找到第一个重复项 (11) 后它不会继续运行? 这是一个效率问题,因为我只想知道是否存在重复。 我不在乎有多少。

public class DuplicateNumbers
{
    public static void main(String[] name)
    {
        int[] myArray = { 64, 17, 9,  55, 2, 11, 11, 1,  8, 23, 13, 13};
        boolean duplicateFound = false;
        while (duplicateFound == false) 
        {
            for(int i = 0; i < myArray.length; i++) 
            {           
                for(int j = i + 1; j < myArray.length; j++)
                {
                    if(myArray[j] == myArray[i])
                    {
                        System.out.println("The number " + myArray[i] + " occurs more than once.");
                        duplicateFound = true;
                    }
                }
            }
        }
        if(duplicateFound == false)
        {
            System.out.println("There are no duplicates.");
        }
        System.out.println("Array length is " + myArray.length);
    }
}

【问题讨论】:

  • 如果你说这是什么语言会很有帮助。一般来说,大多数有循环的语言都有一些中断/继续功能来中止这些循环。
  • 您的“while”测试不会每次都进行测试,它会在您到达当前循环结束时进行测试,因此所有“for”循环都将在测试“duplicateFound 值”之前完成。

标签: java while-loop


【解决方案1】:

这里有一个更清晰的写法。请注意,它消除了您可能认为需要 while 循环的内容。它在for 循环中使用return 语句而不是break,在我看来这是一种更简洁的处理循环结果的方式。

public class DuplicateNumbers
{
  private static boolean hasDuplicates(int[] myArray) {
    for(int i = 0; i < myArray.length; i++) 
    {           
      for(int j = i + 1; j < myArray.length; j++)
      {
        if(myArray[j] == myArray[i])
        {
           System.out.println("The number " + myArray[i] + " occurs more than once.");
           return true;
        }
      }
    }
    return false;
  }

  public static void main(String[] name)
  {
     int[] myArray = { 64, 17, 9,  55, 2, 11, 11, 1,  8, 23, 13, 13};
     if (!hasDuplicates(myArray)) {
        System.out.println("There are no duplicates.");
    }
    System.out.println("Array length is " + myArray.length);
  }
}

【讨论】:

  • 感谢您的回答,但有一个问题:DuplicateNumbers.java:21: 错误:非静态方法hasDuplicates(int[]) 无法从静态上下文if (!hasDuplicates(myArray)) { 引用^ 1 错误PS:不得不将private boolean hasDuplicates(int[] array) 更改为private boolean hasDuplicates(int[] myArray) 但是为什么这不起作用呢?
  • 好的,还需要将hasDuplicates设为静态。静态方法可以创建类的新实例或调用其他静态方法。因此,解决此问题的另一种方法是 DuplicateNumbers dn = new DuplicateNumbers(); 然后使用 dn.hasDuplicates - 但由于类中没有保存本地状态,因此您只需将 hasDuplicates 设为静态即可。
【解决方案2】:

问题是你的 for 循环没有测试 duplicateFound 条件。如果您想在发生重复时退出每个循环,您可以执行以下操作:

public class DuplicateNumbers {
    public static void main(final String[] name) {
        final int[] myArray = { 64, 17, 9, 55, 2, 11, 11, 1, 8, 23, 13, 13 };
        boolean duplicateFound = false;
        while (duplicateFound == false) {
            for (int i = 0; i < myArray.length && !duplicateFound; i++) {
                for (int j = i + 1; j < myArray.length && !duplicateFound; j++) {
                    if (myArray[j] == myArray[i]) {
                        System.out.println("The number " + myArray[i]
                                + " occurs more than once.");
                        duplicateFound = true;
                    }
                }
            }
        }
        if (duplicateFound == false) {
            System.out.println("There are no duplicates.");
        }
        System.out.println("Array length is " + myArray.length);
    }
}

另一种选择是使用标签和中断语句,尽管我通常不喜欢这种非结构化代码。

例如:

public class DuplicateNumbers {
    public static void main(final String[] name) {
        final int[] myArray = { 64, 17, 9, 55, 2, 11, 11, 1, 8, 23, 13, 13 };
        boolean duplicateFound = false;
        whileLoop: while (duplicateFound == false) {
            for (int i = 0; i < myArray.length; i++) {
                for (int j = i + 1; j < myArray.length; j++) {
                    if (myArray[j] == myArray[i]) {
                        System.out.println("The number " + myArray[i]
                                + " occurs more than once.");
                        duplicateFound = true;
                        break whileLoop;
                    }
                }
            }
        }
        if (duplicateFound == false) {
            System.out.println("There are no duplicates.");
        }
        System.out.println("Array length is " + myArray.length);
    }
}

【讨论】:

    【解决方案3】:

    使用break 离开循环。因为你有嵌套循环,你需要命名循环和命名中断:

    截至 cmets:您不需要 While 循环。如果没有找到重复的,你不想再次重复所有的数组。

     outerFor: for(int i = 0; i < myArray.length; i++) 
     {           
        for(int j = i + 1; j < myArray.length; j++)
        {
            if(myArray[j] == myArray[i])
            {
               System.out.println("The number " + myArray[i] + " occurs more than once.");
               duplicateFound = true;
               break outerFor;
            }
        }
      }
    

    其实你根本不需要休息。当您在一开始遇到重复时,它只会为您节省一些计算时间。

    【讨论】:

    • 当然不需要外部的while?如果没有找到重复项,那只会导致无限循环。
    • @Mike:是的。可以删除。需要打破outerFor然后:)
    【解决方案4】:

    找到重复项后,您只需break;即可。

    System.out.println("The number " + myArray[i] + " occurs more than once.");
    duplicateFound = true;
    break;
    

    【讨论】:

    • 他需要在每个 for 循环中使用 break
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    相关资源
    最近更新 更多