Почему этот цикл не заканчивается? - PullRequest
3 голосов
/ 24 марта 2010

Вот пример кода:

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, цикл завершится.

Почему этого не происходит?

Ответы [ 8 ]

13 голосов
/ 24 марта 2010

Потому что, когда вы получаете 1, вы умножаете на 3 и добавляете 1, возвращая вас к 4.

Тебе нужно еще ЕЩЕ. Я не знаю 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) ;
}

РЕДАКТИРОВАТЬ: как упоминалось в комментариях, вы можете пропустить тест if после else:

if (n % 2 == 0) 
  n = n/2 ; 
else 
  n = ((n*3)+1) ;
2 голосов
/ 24 марта 2010

Я думаю, вам придется изменить 2-й оператор if на else

if (n % 2 == 0)      // if the n is even
  n = n/2 ; 
else                 // if n is odd
  n = ((n*3)+1) ;
1 голос
/ 24 марта 2010

Ответ на вопрос можно прочитать прямо в коде:

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"

на заменяя второй тест другим , вы решаете эту логическую проблему за счет возможного увеличения рекурсии (поскольку в текущей логике две операции иногда выполняются за одну итерацию). Такое исправление также решит более тонкую ошибку , заключающуюся в том, что в текущей версии не все новые значения n выводятся на печать.

Теперь, для дополнительного кредита, докажите, что независимо от начального значения n число рекурсий конечно (то есть последовательность сходится к 1). ; -)

0 голосов
/ 24 марта 2010

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

этот код снова применяется всякий раз, когда вы получаете 1.

поэтому рекурсивная функция будет вызываться неоднократно, что приводит к бесконечному вызову rec, и код никогда не завершится.

0 голосов
/ 24 марта 2010

в дополнение к else if для управления условием, что n нечетно, этой же строке также необходимо добавить & n != 1 в условное выражение Итак, это:

else if (n % 2 != 0 & n != 1) 
0 голосов
/ 24 марта 2010

Работает ли оно, если вы измените его на это?

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

Похоже, вы получаете 2, делите на 2, чтобы получить 1, затем проверяете, есть ли у 1/2 остаток (он есть), и умножаете его на 3 и добавляете 1, чтобы получить 4 ... .

0 голосов
/ 24 марта 2010

при вводе 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)
0 голосов
/ 24 марта 2010

Используйте if / then / else. Ваша логика неверна.

...