3

这是示例代码:

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)则为真 2 将除以 2 得到 1。然后将打印 1,因为(n != 1)为假,循环将终止。

为什么这不会发生?

4

8 回答 8

13

因为当你得到 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) ;
于 2010-03-24T03:14:55.480 回答
2

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

if (n % 2 == 0)      // if the n is even
  n = n/2 ; 
else                 // if n is odd
  n = ((n*3)+1) ;
于 2010-03-24T03:15:24.673 回答
1

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

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)。;-)

于 2010-03-24T03:16:50.890 回答
0

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

于 2010-03-24T03:15:08.383 回答
0

当输入为 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)
于 2010-03-24T03:16:12.237 回答
0

如果你把它改成这样,它会起作用吗?

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

看起来你得到 2,除以 2 得到 1,然后检查 1/2 是否有余数(确实如此),然后将其乘以 3 并加 1,得到 4....

于 2010-03-24T03:16:36.930 回答
0

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

每当您获得 1 时,都会再次执行此代码。

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

于 2010-03-24T05:06:47.087 回答
-1

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

else if (n % 2 != 0 & n != 1) 
于 2010-03-24T03:24:37.630 回答