【问题标题】:Why am I getting an infinite loop of 0's? (Java)为什么我得到一个 0 的无限循环? (爪哇)
【发布时间】:2016-03-18 14:26:33
【问题描述】:

前几天我问了一个关于我的代码的问题,这个令人难以置信的社区很快就解决了这个问题。但是,使用我的代码的重写版本,我遇到了一个完全独立的问题。这是我之前帖子中对该程序的描述。

我正在尝试编写一个程序,该程序可以检测 ArrayList 中任何数字子集可以得出的最大总和,并且总和必须低于用户输入的目标数字。到目前为止,我的程序运行完美,除了一行(没有双关语)。请记住,此代码还不完整。

我现在对代码的问题是,在用户输入一个目标数字后,程序会输出一个 0 的无限循环。即使在尝试调试之后,我仍然会遇到问题。 ArrayList 被完美地应用于程序,但我认为我的 while 循环之一中的某个地方可能有问题。有什么想法吗?

代码如下。

import java.util.*;
class Sum{
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int temp = 0, target = 1, result = 0, firstIndex = 0, secondIndex = 0;
        String tempString = null;
        ArrayList<String> list = new ArrayList<String>();
        ArrayList<Integer> last = new ArrayList<Integer>();
        System.out.println("Enter integers one at a time, pressing enter after each integer Type \"done\" when finished.\nOR just type \"done\" to use the default list.");
        String placehold = "NotDone";

        while (!placehold.equals("done")){
            list.add(input.nextLine());
            placehold = list.get(list.size() - 1);
        }
        list.remove(list.size() - 1);
        if (list.size() == 0){            //Inserts default list if said list is empty
            list.add("1");
            list.add("2");
            list.add("4");
            list.add("5");
            list.add("8");
            list.add("12");
            list.add("15");
            list.add("21");
        }
        for (int i = 0; i < list.size(); i++){
            tempString = list.get(i);
            temp = Integer.parseInt(tempString);     //Changes the items in the list to Integers, which can be inserted into another list and then sorted
            last.add(temp);
        }
        Collections.sort(last);
        System.out.println("Enter the target number");
        target = input.nextInt();
        while (result < target){
            firstIndex = last.size() - 1;
            secondIndex = firstIndex - 1;
            while (last.get(firstIndex) > target){
                firstIndex--;
            }
            if (last.get(firstIndex) + last.get(secondIndex) < result){
                result = last.get(firstIndex) + last.get(secondIndex);
                last.remove(firstIndex);
                last.remove(secondIndex);
                last.add(result);
            }
            else{
                secondIndex--;
            }
            System.out.println(result);
        }  
    }
}

还有输出...

一次输入一个整数,在每个整数后按 Enter 完成后键入“done”。 或者只需键入“完成”即可使用默认列表。

done //提示使用默认列表

输入目标号码

15 //用户输入目标编号

0 0 0 0 0 0 ... //等等

【问题讨论】:

  • 您是否尝试过使用调试器逐行遍历第二个 while 循环以验证 firstIndex/secondIndex 是否始终正确?
  • 实际上,我认为这不是导致问题的索引。不过,我一定会看看的。对我来说可能是一个非常愚蠢的假设。
  • 所以,你必须陷入 while 循环,这意味着结果总是小于目标。结果始终为零...当我们查看结果可以更改的位置时,我们仅在一个位置找到它,而该位置在您的 if 语句中。由于结果永远不会改变,那么 if 语句决不能为真。那么会发生什么?由于 if 语句为假,secondIndex 递减,然后循环重复。然后将 SecondIndex 设置为等于 firstIndex -1,这会将其重置为开始时的状态。你被卡住了!

标签: java while-loop infinite-loop


【解决方案1】:
target = input.nextInt();

应该在你的循环中,否则变量将永远不会改变并且

while(result&lt;target) 永远不会变成假


while(result<target) {
    target = input.nextInt();
    // otherCoolCode
}

【讨论】:

  • 是的,这修复了循环!现在我只需要弄清楚为什么我仍然得到一个 0,但我可以随着时间的推移做到这一点。非常感谢(也感谢“CoolCode”的赞美)。
【解决方案2】:

您在 while 循环之前分配了 target,并且您没有在 while 循环内以任何方式更改 target。您需要在 while 循环中提示用户。否则,如果你将target变量设置为大于0,就会陷入死循环。

【讨论】:

    【解决方案3】:

    问题出在

    if (last.get(firstIndex) + last.get(secondIndex) < result) {
        ...
    }
    

    Result 总是初始化为零,因此条件永远不会为真。 一种可能的解决方法是添加一个额外的条件来处理这种初始情况:

    if (result == 0 || last.get(firstIndex) + last.get(secondIndex) < result) {
        ...
    }
    

    【讨论】:

      【解决方案4】:

      当您有一个循环,其条件在循环的迭代过程中没有改变时,就会发生无限循环。

      让我们回顾一下你的循环:

         while (result < target){
              firstIndex = last.size() - 1;
              secondIndex = firstIndex - 1;
              while (last.get(firstIndex) > target){
                  firstIndex--;
              }
              if (last.get(firstIndex) + last.get(secondIndex) < result){
                  result = last.get(firstIndex) + last.get(secondIndex);
                  last.remove(firstIndex);
                  last.remove(secondIndex);
                  last.add(result);
              }
              else{
                  secondIndex--;
              }
              System.out.println(result);
          }  
      

      只有当result 和/或target 更改为result &lt; target 为假时,您的循环才会结束。

      在你的循环中,只有当(last.get(firstIndex) + last.get(secondIndex) &lt; result) 为真时,你才分配给result。因此,如果该条件为假,则结果将不会改变。

      您有一些不在循环条件本身但由循环操纵的附加状态:firstIndexsecondIndex。您分配给它们的循环的每次迭代。您确实有一个 'else' 子句,您在打印 result 的当前值之前修改 secondIndex然而 然后您立即在顶部分配给它循环。

      这是你无限循环的症结(当last.get(firstIndex) + last.get(secondIndex) &lt; result 为假时)

      1. result 不变
      2. 您的列表last 未修改,因此last.size()-1firstIndex - 1 保持不变
      3. 您指定secondIndex = firstIndex - 1; 覆盖循环结束时的减量,因此firstIndexsecondIndex 都不会改变

      【讨论】:

      • 实际上,result = last.get(firstIndex) + last.get(secondIndex); 行中的结果更改...只是我只允许根据我的程序功能进行更改时更改。此外,在这里重新分配 secondIndex 实际上是可能的,因为当进行修改时,ArrayList 的大小发生了变化,并且不会重新初始化为相同的索引。但是,如果我没有进行任何修改,我确实看到了出现的问题。修改基本上在循环开始时被反转。我认为这将解决“0”问题
      • 对:你修改resultlast只有当条件为真时。当条件为假时,你就有了无限循环。
      【解决方案5】:

      在这一行

      if (last.get(firstIndex) + last.get(secondIndex) < result) {
      

      两个值的总和几乎不会小于结果,即“0”。

      【讨论】:

        猜你喜欢
        • 2011-08-18
        • 2013-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-24
        • 2022-10-16
        • 2021-08-31
        相关资源
        最近更新 更多