在这种情况下,多个 if 和 if-else 有什么区别?

3
该程序应该在1处停止循环,但由于使用了多个if,它会继续循环。我能够使用if-else完成这个练习,但我很难追踪和理解多个if和if-else之间的差异。
我是新手,所以提前感谢大家的帮助。
public static void main(String[] args) {
    Scanner keyboard = new Scanner(System.in);

    System.out.print("Enter a starting value: ");
    int input = keyboard.nextInt();

    System.out.print(input + ",");
    System.out.print(" ");

    while (input != 1) {
        if (input % 2 == 0) {
            input = input / 2;
            System.out.print(input + ",");
            System.out.print(" ");
        }
        if (input % 2 == 1) { // replace with else
            input = 3 * input + 1;
            System.out.print(input + ",");
            System.out.print(" ");
        }
    }

    keyboard.close();
}

预期结果:程序应该在1处停止(while循环检查)

实际结果:它继续无限循环:4 2 1 4 2 1 ....


你需要使用 else if。如果 (input % 2 == 1) - Vivek Mangal
2
即使在多个if语句中通过了前一个条件,每个if条件都会被检查。但是在if-else块中,如果有任何一个条件通过,则其他条件将被跳过。 - mallikarjun
你可以输入任何整数。例如:请输入起始值:1919、58、29、88、44、22、11、34、17、52、26、13、40、20、10、5、16、8、4、2、1。 - Linh Nguyen Viet
通常情况下,您不应关闭打开System.inScanner,如果关闭它,您将无法在程序中稍后再次打开System.in。最好抑制System.in的警告并关闭不是System.in的流。 - Nexevis
@Nexevis 我刚开始学习编程,所以我会按照课堂指导来做,但还是谢谢你的建议。 - Linh Nguyen Viet
7个回答

7
因为起始值为4,第一个if语句将其减少到2。在循环的下一次迭代中,第一个if语句将其减少到1,但是然后第二个if语句发现它是奇数,并将其乘以3并加上1
要解决这个问题,您需要用else替换第二个if语句,因为只有两种可能的情况:
if (input % 2 == 0) {
    input = input / 2;
} else {
    input = 3 * input + 1;
}

System.out.print(input + ", ");

这将使得如果第一个if语句被执行,那么第二个if语句就不会被执行。

1
谢谢,Jacob。我现在明白了。我以为多个if会同时被检查。比如2进去,2个if同时检查,但只有第一个通过,然后将其减少到1。然后while检查失败并停止。 - Linh Nguyen Viet

1

当输入值为2进入while循环时,它会进入第一个if语句块,在离开该块时其值变为1。然后它进入第二个if语句块并将其值设为4。接下来有一个新的循环,其值为4 2 1 ...


1

想象一下当输入为2的情况

情况1. 采用两个if语句,第一个if语句将输入变为1,第二个if语句将被执行并再次将其变为4。

情况2. 采用if else语句,一旦第一个if语句使输入变为1,它将退出循环,因此得出结果。


1
在多个if语句中,即使前一个条件已经通过或失败,每个if条件都会被检查。但是,在if-else块的情况下,如果有任何一个条件通过,则其他条件将被跳过。

1
不是一个答案,但与Collatz序列相关。
(错误在于输入第一个if更改了input,导致如果没有else,会进入第二个if。)
1 -> 1
odd n -> 3n+1 (even!)
even n -> n/2

正如您所看到的,奇数 n 可以通过缩短两个步骤来进行优化:

odd n ->-> (3n+1)/2

对于数学研究而言,这是更好的顺序。

然后你可以完全不使用 else

while (input != 1) {
    if (input % 2 == 1) {
        input = 3 * input + 1;
        System.out.print(input + ",");
        System.out.print(" ");
    }
    /*if (input % 2 == 0)*/ {
        input /= 2;
        System.out.print(input + ",");
        System.out.print(" ");
    }
}

1

当变量input的值为1时,while循环将继续迭代。在您的示例中,当输入为4时,会有无限次迭代(根据条件,循环将无限执行)

在while循环之前,它会打印出4(即输入值)

迭代1:输入为4。进入while循环 -> 进入第一个if,因为4%2=0并重新分配输入为4/2=2 -> 打印2 -> 不进入第二个if,因为2%2=0

迭代2:输入为2。进入while循环 -> 进入第一个if,因为2%2=0并重新分配输入为2/2=1。打印1 -> 进入第二个if,因为现在输入=1且1%2=1。- > 重新分配输入=3×1 + 1 = 4。打印4

然后它再次从4开始。 它将无限地继续打印4 2 1 4 2 1 4 2 1 ...

while (input != 1) {
        //1st if
        if (input % 2 == 0) {
            input = input / 2;
            System.out.print(input + ",");
            System.out.print(" ");
        }
        //2nd if
        if (input % 2 == 1) { // replace with else
            input = 3 * input + 1;
            System.out.print(input + ",");
            System.out.print(" ");
        }
}

当if条件失败时,else语句才会执行。当您将第二个if条件替换为else语句时,程序将不会再次将输入值分配给4。因此它将停止在1处,打印4 2 1


0

试试这个:

while (input != 1) {
    if (input % 2 == 0) {
        input = input / 2;
        System.out.print(input + ",");
        System.out.print(" ");
    }
    else { // replace with else
        input = 3 * input + 1;
        System.out.print(input + ",");
        System.out.print(" ");
    }
}

在你的代码中:

while (input != 1) {
    if (input % 2 == 0) {
        input = input / 2;
        System.out.print(input + ",");
        System.out.print(" ");
    }
    if (input % 2 == 1) { // replace with else
        input = 3 * input + 1;
        System.out.print(input + ",");
        System.out.print(" ");
    }
}

在你的代码中,如果输入是2,那么`input = input / 2;`这个语句会使得input变为1。接下来,由于`input % 2 == 1`会成为真,它会使得input等于4(`input = 3 * input + 1;`),而循环将不会结束。你应该使用else。即使代码被注释为`// replace with else`。

4
请添加解释,只有代码而没有解释并不太有帮助。 - Nexevis
1
@vivek mangal 那其实是我的评论。我的意思是,我用else完成了它,但并没有完全理解为什么多个if也不起作用。但是你的解释非常有帮助。谢谢。 - Linh Nguyen Viet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接