Поиск самой длинной цепочки в последовательности Коллатца на Java, цикл не завершается

Я хочу применить последовательность Коллатца и применить ее ко всем числам от 1 до 10 ^ 6 и вернуть число с наибольшей цепочкой, необходимой для достижения 1. Однако у меня есть проблема, что мои циклы не заканчиваются в Eclipse, и я не могу понять, почему, я даже не могу отобразить все свои отпечатки в консоли, несмотря на то, что хочу этого на каждом шагу.

Последовательность Коллатца вычисляется по следующим правилам:

  • если n нечетное, следующее число равно n/2

  • если n четно, следующее число 3n + 1

Это то, что у меня есть до сих пор:

public static long collatz() {

    long res = 0;
    long n = 1;
    long count = 0;
    long largestCount = 0;
    long t = 0;

    for (long k = 1; k <= 20; k++) {

        n = k;

        while (n != 1) {

            if ((n % 2) == 0) {
                n = n / 2;
                count = count + 1;
            }

            else {
                n = (3 * n) + 1;
                count = count + 1;

            }

            if (count > largestCount) {
                largestCount = count;
                res = k;
            }
        }
    }

    System.out.println(res);
    return res;

}

person Cat Tran    schedule 01.05.2016    source источник
comment
Вы ждали достаточно долго? Я изменил k <= 1000000 на k <= 20, и эта программа вышла.   -  person MikeCAT    schedule 01.05.2016
comment
это должно выполняться нормально. тот факт, что вы печатаете кучу материала, вызывает задержку   -  person Debosmit Ray    schedule 01.05.2016
comment
В соответствии с этой симуляцией печатается 264 868 848 строк + 1 (результат: строка). Зачем тебе столько строк?   -  person MikeCAT    schedule 01.05.2016
comment
Спасибо за ваши ответы. Я удалил отпечатки и изменил k на k‹=20, однако он все равно не запускается.   -  person Cat Tran    schedule 01.05.2016


Ответы (4)


Ваш код должен работать правильно. Однако это не рабочий код. Вы проверяете условие, чтобы увидеть, больше ли текущее count, чем текущее largest count внутри цикла while, что на самом деле не имеет смысла, поскольку вам нужно получить длину последовательности коллаца, а затем сравнить до текущего максимума. В остальном ваш код хорош. :)

Это то, что я написал, если вам интересно.

final int number = 1000000;

long sequenceLength = 0;
long startingNumber = 0;
long sequence;

for (int i = 2; i <= number; i++) {
    int length = 1;
    sequence = i;
    while (sequence != 1) {
        if ((sequence % 2) == 0) {
            sequence = sequence / 2;
        } else {
            sequence = sequence * 3 + 1;
        }
        length++;
    }

    //Check if sequence is the best solution
    if (length > sequenceLength) {
        sequenceLength = length;
        startingNumber = i;
    }
}
System.out.println(startingNumber);
person Debosmit Ray    schedule 01.05.2016
comment
спасибо за ваш ответ, но можете ли вы объяснить разницу в вашем коде с моим? он выглядит так же для меня, за исключением отпечатков, которые были у меня. - person Cat Tran; 01.05.2016
comment
@CatTran Конечно! Вы проверяли условие, чтобы увидеть, больше ли текущий count текущего наибольшего количества внутри цикла while, что на самом деле не имеет смысла, поскольку вам нужно получить длину последовательности коллатца, а затем , проверьте его размер. В остальном ваш код хорош. :) - person Debosmit Ray; 01.05.2016
comment
@CatTran Было бы неплохо, если бы вы могли принять / проголосовать за ответ, если ваша проблема решена или близка к разрешению. Взято из здесь. Принятие ответа важно, так как оно вознаграждает плакаты за решения вашей проблемы и информирует других о том, что ваша проблема решена. - person Debosmit Ray; 01.05.2016
comment
А, хорошо, я понял. Еще раз спасибо. Извините, что не принял, это мой первый пост в stackoverflow. - person Cat Tran; 01.05.2016

Он работает, но всегда будет печатать последнее проверенное число, так как вы не сбрасываете count.

Я также переместил приращение значения count из оператора if/else, так как приращение не зависит от значения n.

И я перенес обновление largestCount после цикла while.

public static long collatz() {

    long res = 0;
    long n = 1;
    long count = 0;
    long largestCount = 0;
    long t = 0;

    for (long k = 1; k <= 20; k++) {

        n = k;
        count = 0; // start every sequence with count = 0

        while (n != 1) {

            if ((n % 2) == 0) {
                n = n / 2;
            }
            else {
                n = (3 * n) + 1;
            }
            count = count + 1;
        }
        if (count > largestCount) {
            largestCount = count;
            res = k;
        }
    }

    System.out.println(res);
    return res;
}
person Thomas Kläger    schedule 01.05.2016

Если вы прочтете мое решение, то увидите, что написание комментариев к тому, что должна делать группа строк кода, очень полезно и делает код самодокументированным.

Попробовать онлайн

public static long collatz(int maxN)
{
    long res = 0, n = 1, count = 0, largestCount = 0, t = 0;

    // for K in [1, max-N]
    for (long k = 1; k <= maxN; k++)
    {
        // reset count to zero
        n = k; count = 0;

        // count how many steps to get to 1
        while (n != 1)
        {
            // n = collatz(n)
            n = (n%2==0 ? n/2 : (3*n)+1);

            count++; // count the step
        }

        // check for maximum count
        if (count > largestCount)
        {
            largestCount = count;
            res = k;
        }
    }

    return res; // return maximum solution
}
person Khaled.K    schedule 01.05.2016

Используйте Biginteger вместо Long в C# или Visual Basic

например http://herbert-helling.de/VB_Tests/

person User9123    schedule 03.05.2016