Java, эквивалентный из станд.:: двухсторонняя очередь

Вы делаете a = collatz(a), но так как ваша функция не имеет операторов возврата, это устанавливает a в Нет. Затем в следующей итерации цикла вы попытаетесь выполнить арифметику для a. Это терпит неудачу, потому что вы не можете делать арифметику None.

Тебе вообще не нужна рекурсия. У вас уже есть цикл, так что вы можете просто удалить эти коллатц-вызовы.

def collatz(a):
    while (a != 1):

        if a%2 == 0:
            a = a//2
            print (a, " -> ")
        elif a%2 != 0:
            a = int(3*a + 1)
            print (a, " -> ")


x = int(input("Enter a number: "))
collatz(x)

... Но если у вас нет шансов на рекурсию, вы тоже можете это сделать. Удалите цикл while и вызовите collatz в конце вашей функции.

def collatz(a):
    if a == 1:
        return
    if a%2 == 0:
        a = a//2
    elif a%2 != 0:
        a = int(3*a + 1)
    print (a, " -> ")
    collatz(a)

Недостаток этого подхода заключается в том, что он будет аварийно завершать работу с «превышением максимальной глубины рекурсии», если функция повторяется более 999 раз. Последовательности Коллатца сходятся к 1 довольно быстро, так что это, вероятно, не является практической проблемой для этого конкретного алгоритма, но об этом следует помнить при написании любой рекурсивной функции.


Оба эти подхода имеют потенциально нежелательное поведение печати «->» после последнего номера в последовательности. Это довольно распространенная проблема в этом стиле кода «печать во время итерации». Одно из возможных решений - удалить вызовы печати из функции, вместо этого возвращая список значений последовательности. Затем вы можете оформить вывод после факта, используя join, чтобы перемежать числа стрелками.

def collatz(a):
    result = [a]
    while (a != 1):

        if a%2 == 0:
            a = a//2
        elif a%2 != 0:
            a = int(3*a + 1)
        result.append(a)
    return result

x = int(input("Enter a number: "))
seq = collatz(x)
print(" -> ".join(str(num) for num in seq))
11
задан Jason S 24 December 2008 в 03:31
поделиться

3 ответа

Примитивные Наборы для Java имеют ArrayDeque с получением (интервал idx) метод.

http://sourceforge.net/projects/pcj

Я не могу ручаться за качество этого проекта все же.

Альтернатива должна была бы получить источник JDK ArrayDeque и добавить получение (интервал idx) метод самостоятельно. Должно быть относительно легким.

Править: Если бы Вы намереваетесь использовать двухстороннюю очередь очень многопоточным способом, я пошел бы "патч ArrayDeque JDK" маршрут. Эта реализация была протестирована полностью и используется в новой платформе java.util.concurrent ForkJoin.

10
ответ дан 3 December 2019 в 10:05
поделиться

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

0
ответ дан 3 December 2019 в 10:05
поделиться

Интересный... Я только заканчивал читать Дженерики Java и Наборы, и это имеет краткое обсуждение этого вида набора включая ссылку на Новостную рассылку специалистов по Java, которая включает CircularArrayList, который мог бы сделать то, в чем я нуждаюсь.

0
ответ дан 3 December 2019 в 10:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: