具有多个数的欧几里得算法(GCD)?

时间:2013-05-18 19:19:32

标签: python math greatest-common-divisor

所以我正在用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))

10 个答案:

答案 0 :(得分:29)

由于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只在原始调用中执行),这具有永不溢出堆栈的额外好处。 / p>

答案 1 :(得分:26)

您可以使用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
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.

答案 2 :(得分:3)

GCD运算符是可交换的和关联的。这意味着

gcd(a,b,c) = gcd(gcd(a,b),c) = gcd(a,gcd(b,c))

因此,一旦您知道如何为2个数字执行此操作,就可以为任何数字执行此操作


要为两个数字做这个,你只需要实现Euclid的公式,这就是:

// 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)定义为:

if (len(nums) == 1)
  return nums[1]
else
  return euclid(nums[1], gcd(nums[:2]))

这使用gcd()的associative属性来计算答案

答案 3 :(得分:3)

找出 PYTHON 中两个以上数字的 LCM 的解决方案如下:

insert 1 :

db.test.insert(
   {
        "companyId" : "123",
        "persons" : [
                {
                        "joiningDate" : NumberLong("1431674741623"),
                         "name" : "Rajesh"
                }
        ],

})

insert 2 :

db.test.insert(
   {
        "companyId" : "123",
        "persons" : [
                {
                        "joiningDate" : NumberLong("1431674741653"),
                         "name" : "Rahul"
                }
        ],

})

这里我在 range()函数的最后一个参数中添加了+1,因为函数本身从零(0)开始到n-1。单击超链接以了解有关range()功能的更多信息:

#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)

那些不熟悉python的人可以通过给定的链接阅读更多关于reduce()函数的信息。

答案 4 :(得分:3)

Python 3.9 math.gcd的多参数版本,因此您可以使用:

import math
math.gcd(30, 40, 36)

3.5 <= Python <= 3.8.x:

import functools
import math
functools.reduce(math.gcd, (30, 40, 36))

3 <= Python <3.5:

import fractions
import functools
functools.reduce(fractions.gcd, (30, 40, 36))

答案 5 :(得分:0)

尝试按以下方式调用GCD()

i = 0
temp = numbers[i]
for i in range(len(numbers)-1):
        temp = GCD(numbers[i+1], temp)

答案 6 :(得分:0)

我用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=[]) # []

一些动态我的理解:

例如[8,18]-> [18,8]-> [8,2]-> [2,0]

18 = 8x + 2 =(2y)x + 2 = 2z,其中z = xy +1

例如[18,22]-> [22,18]-> [18,4]-> [4,2]-> [2,0]

22 = 18w + 4 =(4x + 2)w + 4 =((2y)x + 2)w + 2 = 2z

答案 7 :(得分:0)

从python 3.9 beta 4开始,它已内置支持在数字列表上查找gcd。

Python 3.9.0b4 (v3.9.0b4:69dec9c8d2, Jul  2 2020, 18:41:53)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> A = [30, 40, 36]
>>> print(math.gcd(*A))
2

答案 8 :(得分:0)

问题之一是,许多计算仅适用于大于1的数字。我修改了找到的here解决方案,使其接受小于1的数字。基本上,我们可以使用最小值,然后使用该最小值来计算小于1的数字的GCD。

# GCD of more than two (or array) numbers - alows folating point numbers
# Function implements the Euclidian algorithm to find H.C.F. of two number 
def find_gcd(x, y): 
    while(y): 
        x, y = y, x % y 
    return x 
          
# Driver Code         
l_org = [60e-6, 20e-6, 30e-6]
min_val = min(l_org)
l = [item/min_val for item in l_org]
  
num1 = l[0] 
num2 = l[1] 
gcd = find_gcd(num1, num2) 
  
for i in range(2, len(l)): 
    gcd = find_gcd(gcd, l[i]) 
      
gcd = gcd * min_val
print(gcd) 

答案 9 :(得分:0)

这里是查找2个数字的GCD的简单方法

a = int(input("Enter the value of first number:"))
b = int(input("Enter the value of second number:"))
c,d = a,b
while a!=0:
    b,a=a,b%a
print("GCD of ",c,"and",d,"is",b)
相关问题