#python #recursion #iteration
#python #рекурсия #итерация
Вопрос:
Прежде всего, то, что я пытаюсь сделать, НЕ является наибольшим ОБЩИМ делителем. Я пытаюсь найти наибольший делитель. Например, для числа 12 мой наибольший делитель будет равен 6. Для числа 15 это будет 5, а для 17 — 1.
То, что я сделал, было это с итерацией :
def greatest_divisor(n):
for d in range(n-1,0,-1):
if n % d == 0:
return d
break
greatest_divisor(12)
>6
который работает правильно.
Что мне нужно, так это рекурсивная форма этой функции. Если вы могли бы придумать что-то работающее, я ценю это!
Комментарии:
1. разве 12 сам по себе не является наибольшим делителем?
2. Я не понимаю, как рекурсия поможет здесь. Наибольший делитель делителя всегда будет меньше указанного делителя. Также вы можете изменить начальную точку вашей итерации на
floor(n/2)
asn
, которая никогда не может быть разделена на что-либо большее, чемn/2
.
Ответ №1:
В общем случае вам потребуется меньше итераций, если сначала вы найдете наименьший делитель (больше 1), а затем разделите n на этот делитель, чтобы получить наибольшее. В этом случае вам не нужно повторять больше, чем до квадратного корня из n . Если ничего не найдено, верните 1.
Вот итеративное решение для этого:
def greatest_divisor(n):
for low in range(2, int(n**0.5) 1):
if n % low == 0:
return n // low
return 1
На самом деле нет никакой выгоды в том, чтобы сделать это рекурсивным, поскольку это будет просто случай хвостовой рекурсии:
def greatest_divisor(n, low=2):
if n % low == 0:
return n // low
if low*low > n:
return 1
return greatest_divisor(n, low 1)
Комментарии:
1. Я думал улучшить свой ответ, но ваш уже содержит то, что я хотел добавить…
Ответ №2:
Сначала я бы начал с математического замечания: найти наибольший делитель — это то же самое, что найти наименьший делитель (но 1), и этот наименьший делитель будет простым. Это свойство может привести к более эффективным алгоритмам, если вы хотите искать большое количество значений.
Далее любой итеративный метод можно переписать как рекурсивный, определив начальную точку и условие остановки. Обычно этого избегают, потому что рекурсивные методы влияют на стек и прерываются, если вы повторяете слишком глубоко, в то время как итеративные методы могут требовать только постоянных ресурсов.
Итак, здесь прямое преобразование вашего собственного кода:
def r_greatest_divisor(n, cur=None):
if cur is None:
cur = n - 1
if cur <= 1:
return 1
if n % cur == 0:
return cur
return r_greatest_divisor(n, cur - 1)