为什么这个循环不终止?

发布于 2024-08-27 01:38:30 字数 425 浏览 9 评论 0原文

下面是示例代码:

public static void col (int n) 
{
    if (n % 2 == 0) 
       n = n/2 ; 
    if (n % 2 != 0) 
       n = ((n*3)+1) ;

    System.out.println (n) ;
    if (n != 1) 
       col (n) ;
}

它工作得很好,直到它下降到 2。然后它无限地输出 2 4 2 4 2 4 2 4 2 4。在我看来,如果 2 作为 n 输入,则 (n % 2 == 0) 为 true 2 将除以 2 得到 1。然后 1 将被打印,因为 ( n != 1) 为 false 循环将终止。

为什么这不会发生?

Here's the sample code:

public static void col (int n) 
{
    if (n % 2 == 0) 
       n = n/2 ; 
    if (n % 2 != 0) 
       n = ((n*3)+1) ;

    System.out.println (n) ;
    if (n != 1) 
       col (n) ;
}

this works just fine until it gets down to 2. then it outputs 2 4 2 4 2 4 2 4 2 4 infinitely. it seems to me that if 2 is entered as n then (n % 2 == 0) is true 2 will be divided by 2 to yeild 1. then 1 will be printed and since (n != 1) is false the loop will terminate.

Why doesn't this happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

倥絔 2024-09-03 01:38:30

因为当你达到 1 时,你需要乘以 3 再加上 1,回到 4。

你需要一个 ELSE 在那里。我不知道java,但它看起来像:

public static void col (int n) 
{
    if (n % 2 == 0) 
      n = n/2 ; 
    else if (n % 2 != 0) 
      n = ((n*3)+1) ;

    System.out.println (n) ;
    if (n != 1) 
      col (n) ;
}

编辑:正如评论中提到的,您可以在 else 之后省略 if 测试:

if (n % 2 == 0) 
  n = n/2 ; 
else 
  n = ((n*3)+1) ;

Because when you get to 1, you are multiplying by 3 and adding 1, taking you back to 4.

You need an ELSE in there. I don't know java, but it would look something like:

public static void col (int n) 
{
    if (n % 2 == 0) 
      n = n/2 ; 
    else if (n % 2 != 0) 
      n = ((n*3)+1) ;

    System.out.println (n) ;
    if (n != 1) 
      col (n) ;
}

EDIT: as mentioned in the comments, you can omit the if test after the else:

if (n % 2 == 0) 
  n = n/2 ; 
else 
  n = ((n*3)+1) ;
你又不是我 2024-09-03 01:38:30

我认为您必须将第二个 if 语句更改为 else

if (n % 2 == 0)      // if the n is even
  n = n/2 ; 
else                 // if n is odd
  n = ((n*3)+1) ;

I think you'll have to change the 2nd if statement to an else

if (n % 2 == 0)      // if the n is even
  n = n/2 ; 
else                 // if n is odd
  n = ((n*3)+1) ;
羁客 2024-09-03 01:38:30

问题的答案可以直接在代码中读取:

Assume n is 2
(n % 2 == 0) is true therefore n <- 1
(n % 2 != 0) is also true therefore 4 <- n

this warrants a call to function with n = 4,  which is then changed to 2 and
"back to square 1"

通过用 else 替换第二个测试,您可以解决这个逻辑问题,但代价可能是导致更多的递归(因为在当前的逻辑中,有时在一次迭代中执行两个操作)。这样的修复还将解决一个更微妙的错误,即在当前版本中,并非所有新的 n 值都会被打印出来。

现在,为了额外加分,请证明无论 n 的初始值如何,递归次数都是有限的(即序列收敛到 1)。 ;-)

The answer to the question can be read directly in the code:

Assume n is 2
(n % 2 == 0) is true therefore n <- 1
(n % 2 != 0) is also true therefore 4 <- n

this warrants a call to function with n = 4,  which is then changed to 2 and
"back to square 1"

by replacing the second test by an else, you solve this logic problem, at the cost of possibly causing more recursion (since in the current logic, two operations are sometimes performed in one iteration). Such a fix will also solve a more subtle bug, which is that in the current version not all new values of n are printed out.

Now, for extra credit, prove that not matter the initial value of n, the number of recursions is finite (i.e. the sequence converges to 1). ;-)

咆哮 2024-09-03 01:38:30

使用 if/then/else。你的逻辑是错误的。

Use if/then/else. Your logic is wrong.

缱倦旧时光 2024-09-03 01:38:30

当输入为2时:

if (n % 2 == 0)         //true
  n = n/2;              //n = 1 
if (n % 2 != 0)         //true
  n = ((n*3)+1);        //n = 4

System.out.println (n); //prints 4
if (n != 1)             //true
  col (n);              //call col(4)

when the input is 2:

if (n % 2 == 0)         //true
  n = n/2;              //n = 1 
if (n % 2 != 0)         //true
  n = ((n*3)+1);        //n = 4

System.out.println (n); //prints 4
if (n != 1)             //true
  col (n);              //call col(4)
嗳卜坏 2024-09-03 01:38:30

如果改成这样还能用吗?

if (n % 2 == 0) 
    n = n/2 ; 
else if (n % 2 != 0) 
    n = ((n*3)+1) ;

看起来你得到了 2,除以 2 得到 1,然后检查 1/2 是否有余数(有),然后乘以 3 加 1,得到 4....

Does it work if you change it to this?

if (n % 2 == 0) 
    n = n/2 ; 
else if (n % 2 != 0) 
    n = ((n*3)+1) ;

It looks like you're getting 2, dividing by 2 to get 1, then checking to see if 1/2 has a remainder (it does), and multiplying it by 3 and adding 1, to get 4....

我喜欢麦丽素 2024-09-03 01:38:30

如果(n%2!= 0)
n = ((n*3)+1) ;

每当你得到1时,这段代码就会再次实现。

因此,递归函数将被重复调用,从而导致无限的rec调用,并且代码永远不会终止。

if (n % 2 != 0)
n = ((n*3)+1) ;

this code is again implemented whenever u get 1.

therefore the recursive function will be called repeatedly hence leading to an infinite rec calling and code will never terminate.

我早已燃尽 2024-09-03 01:38:30

除了 else if 来控制 n 为奇数的条件之外,同一行还需要 & n != 1 添加到条件中。所以这个:

else if (n % 2 != 0 & n != 1) 

in addition to an else if to govern the condition that n is odd that same line also needs & n != 1 to be added to it within the conditional. So this:

else if (n % 2 != 0 & n != 1) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文