Алгоритм Евклида (НОД) нескольких чисел?
поэтому я пишу программу на Python, чтобы получить GCD любого количества чисел.
def GCD(numbers):
if numbers[-1] == 0:
return numbers[0]
# i'm stuck here, this is wrong
for i in range(len(numbers)-1):
print GCD([numbers[i+1], numbers[i] % numbers[i+1]])
print GCD(30, 40, 36)
функция принимает список чисел. Это должно вывести 2. Однако я не понимаю, как использовать алгоритм рекурсивно, чтобы он мог обрабатывать несколько чисел. Кто-нибудь может объяснить?
обновлено, все еще не работает:
def GCD(numbers):
if numbers[-1] == 0:
return numbers[0]
gcd = 0
for i in range(len(numbers)):
gcd = GCD([numbers[i+1], numbers[i] % numbers[i+1]])
gcdtemp = GCD([gcd, numbers[i+2]])
gcd = gcdtemp
return gcd
хорошо, решил это
def GCD(a, b):
if b == 0:
return a
else:
return GCD(b, a % b)
а затем используйте reduce, например
reduce(GCD, (30, 40, 36))
6 ответов
поскольку GCD ассоциативен,GCD(a,b,c,d)
это то же самое, что GCD(GCD(GCD(a,b),c),d)
. В этом случае Python reduce
функция была бы хорошим кандидатом для уменьшения случаев, для которых len(numbers) > 2
для простого сравнения 2-х чисел. Код будет выглядеть примерно так:
if len(numbers) > 2:
return reduce(lambda x,y: GCD([x,y]), numbers)
Reduce применяет данную функцию к каждому элементу в списке, так что что-то вроде
gcd = reduce(lambda x,y:GCD([x,y]),[a,b,c,d])
это то же самое, что делать
gcd = GCD(a,b)
gcd = GCD(gcd,c)
gcd = GCD(gcd,d)
теперь осталось только код после len(numbers) <= 2
. Передача только двух аргументов GCD
на reduce
гарантирует, что ваша функция повторяется более одного раза (после len(numbers) > 2
только в исходном вызове), который имеет дополнительное преимущество никогда не переполнять стек.
можно использовать reduce
:
>>> from fractions import gcd
>>> reduce(gcd,(30,40,60))
10
что эквивалентно;
>>> lis = (30,40,60,70)
>>> res = gcd(*lis[:2]) #get the gcd of first two numbers
>>> for x in lis[2:]: #now iterate over the list starting from the 3rd element
... res = gcd(res,x)
>>> res
10
помогите on reduce
:
>>> reduce?
Type: builtin_function_or_method
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
оператор GCD является коммутативным и ассоциативным. Это значит, что
gcd(a,b,c) = gcd(gcd(a,b),c) = gcd(a,gcd(b,c))
Итак, как только вы знаете, как это сделать для 2 чисел, вы можете сделать это для любого числа
чтобы сделать это для двух чисел, вам просто нужно реализовать формулу Евклида, которая просто:
// Ensure a >= b >= 1, flip a and b if necessary
while b > 0
t = a % b
a = b
b = t
end
return a
определите эту функцию как, скажем euclid(a,b)
. Затем, вы можете определить gcd(nums)
as:
if (len(nums) == 1)
return nums[1]
else
return euclid(nums[1], gcd(nums[:2]))
Это использует ассоциативное свойство gcd () для вычисления ответа
решение узнать LCM более двух чисел в PYTHON следующим образом:
#finding LCM (Least Common Multiple) of a series of numbers
def GCD(a, b):
#Gives greatest common divisor using Euclid's Algorithm.
while b:
a, b = b, a % b
return a
def LCM(a, b):
#gives lowest common multiple of two numbers
return a * b // GCD(a, b)
def LCMM(*args):
#gives LCM of a list of numbers passed as argument
return reduce(LCM, args)
здесь я добавил +1 в последний довод range ()
попробуйте вызвать GCD()
следующим образом:
i = 0
temp = numbers[i]
for i in range(len(numbers)-1):
temp = GCD(numbers[i+1], temp)
мой способ решения в Python. Надеюсь, это поможет.
def find_gcd(arr):
if len(arr) <= 1:
return arr
else:
for i in range(len(arr)-1):
a = arr[i]
b = arr[i+1]
while b:
a, b = b, a%b
arr[i+1] = a
return a
def main(array):
print(find_gcd(array))
main(array=[8, 18, 22, 24]) # 2
main(array=[8, 24]) # 8
main(array=[5]) # [5]
main(array=[]) # []
некоторая динамика, как я ее понимаю:
ex.[8, 18] -> [18, 8] -> [8, 2] -> [2, 0]
18 = 8x + 2 = (2y)x + 2 = 2z, где z = xy + 1
ex.[18, 22] -> [22, 18] -> [18, 4] -> [4, 2] -> [2, 0]
22 = 18w + 4 = (4x+2)w + 4 = ((2y)x + 2)w + 2 = 2z