Python中最大公约数的代码[关闭]


108

a和b的最大公约数(GCD)是将它们两个都除而无余的最大数。

查找两个数的GCD的一种方法是Euclid算法,该算法基于以下观察结果:如果ra则除以b,则gcd(a, b) = gcd(b, r)。作为基本案例,我们可以使用gcd(a, 0) = a

写一个函数调用GCD是需要的参数ab返回他们的最大公约数。



尝试`np.gcd.reduce” 这里
uhoh

Answers:


300

在标准库中

>>> from fractions import gcd
>>> gcd(20,8)
4

来自inspectPython 2.7中模块的源代码:

>>> print inspect.getsource(gcd)
def gcd(a, b):
    """Calculate the Greatest Common Divisor of a and b.

    Unless b==0, the result will have the same sign as b (so that when
    b is divided by it, the result comes out positive).
    """
    while b:
        a, b = b, a%b
    return a

从Python 3.5开始,gcd math模块中;那个在fractions被弃用。而且,inspect.getsource不再为这两种方法返回说明性的源代码。


3
它不返回“的_largest_数就是两个人没有余鸿沟”例如,fractions.gcd(1, -1)-11 > -11整除1-1没有余,它是大于-1,看到bugs.python.org/issue22477
JFS

1
@JFSebastian我不认为这是一个问题...只需查看源代码中的注释:“除非b == 0,否则结果将与b具有相同的符号”,因此gcd(1, -1) == -1对我来说似乎完全合法。
Marco Bonelli,2015年

@MarcoBonelli:是的。它的行为与所记录的一样,但不是大多数人所熟悉的教科书定义。阅读我上面链接的讨论。就我个人而言,我喜欢fractions.gcd()它(它适用于欧几里得环元素)。
jfs 2015年

1
从Python 3.5开始,@ JFSebastian FWIW math.gcd(1, -1)返回1
Acumenus '16

1
@ABB math.gcd()和fractions.gcd()在答案和注释中有所不同。
jfs

39

mn的算法可以运行很长时间。

这个执行得更好:

def gcd(x, y):
    while y != 0:
        (x, y) = (y, x % y)
    return x

5
这也是标准库中的那个。
sayantankhan 2014年

10
该算法甚至如何工作?就像魔术。
dooderson 2014年

20
@netom:不,作业不能这样写;元组分配x在分配之前使用。您已分配yx first,因此现在y将被设置为0y % y始终为0)。
马丁·彼得斯

1
@MartijnPieters是的,是的,我应该使用一个临时变量。像这样:x_ = y; y = x%y; x = x_
netom

3
@netom:使用此答案中的元组分配时根本不需要。
马丁·彼得斯

18

此版本的代码利用Euclid算法查找GCD。

def gcd_recursive(a, b):
    if b == 0:
        return a
    else:
        return gcd_recursive(b, a % b)

28
您在名称中使用了iter,但实际上是递归版本。
Shiplu Mokaddim '16

相比于循环版本递归是高效不佳,+则需要用b调用它>一
Goulu博士

1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
安德烈亚斯·K


3
def gcd(m,n):
    return gcd(abs(m-n), min(m, n)) if (m-n) else n

5
当您要比较相等时,切勿使用“ is”。小整数缓存是CPython实现的详细信息。
Marius Gedminas

2

使用递归的非常简洁的解决方案:

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a%b)

2

使用递归

def gcd(a,b):
    return a if not b else gcd(b, a%b)

使用while

def gcd(a,b):
  while b:
    a,b = b, a%b
  return a

使用lambda,

gcd = lambda a,b : a if not b else gcd(b, a%b)

>>> gcd(10,20)
>>> 10

1
Lambda版本无法工作,因为它没有条件可以停止递归。我认为这只是在调用您先前定义的函数。
rem

1
a=int(raw_input('1st no \n'))
b=int(raw_input('2nd no \n'))

def gcd(m,n):
    z=abs(m-n)
    if (m-n)==0:
        return n
    else:
        return gcd(z,min(m,n))


print gcd(a,b)

一种基于euclid算法的不同方法。


1
def gcdRecur(a, b):
    '''
    a, b: positive integers

    returns: a positive integer, the greatest common divisor of a & b.
    '''
    # Base case is when b = 0
    if b == 0:
        return a

    # Recursive case
    return gcdRecur(b, a % b)

1

我认为另一种方法是使用递归。这是我的代码:

def gcd(a, b):
    if a > b:
        c = a - b
        gcd(b, c)
    elif a < b:
        c = b - a
        gcd(a, c)
    else:
        return a

您不递归调用后返回...尝试运行gcd(10,5)...
Tomerikoo

0

在Python中递归:

def gcd(a, b):
    if a%b == 0:
        return b
    return gcd(b, a%b)

0
def gcd(a,b):
    if b > a:
        return gcd(b,a)
    r = a%b
    if r == 0:
        return b
    return gcd(r,b)

0

对于a>b

def gcd(a, b):

    if(a<b):
        a,b=b,a
        
    while(b!=0):
        r,b=b,a%r
        a=r
    return a

对于a>ba<b

def gcd(a, b):

    t = min(a, b)

    # Keep looping until t divides both a & b evenly
    while a % t != 0 or b % t != 0:
        t -= 1

    return t

4
python中的swap vars是儿童游戏:b, a = a, b。尝试阅读更多有关该语言的信息
Jason Hu

3
我喜欢你说的话,但我不喜欢你说的话
JackyZhu

0

我必须使用while循环对作业进行类似的操作。这不是最有效的方法,但是如果您不想使用某个函数,则可以使用该方法:

num1 = 20
num1_list = []
num2 = 40
num2_list = []
x = 1
y = 1
while x <= num1:
    if num1 % x == 0:
        num1_list.append(x)
    x += 1
while y <= num2:
    if num2 % y == 0:
        num2_list.append(y)
    y += 1
xy = list(set(num1_list).intersection(num2_list))
print(xy[-1])

0
def _grateest_common_devisor_euclid(p, q):
    if q==0 :
        return p
    else:
        reminder = p%q
        return _grateest_common_devisor_euclid(q, reminder)

print(_grateest_common_devisor_euclid(8,3))

-1

这段代码根据#用户给定的选择计算出两个以上的数字的gcd,此处由用户给出数字

numbers = [];
count = input ("HOW MANY NUMBERS YOU WANT TO CALCULATE GCD?\n")
for i in range(0, count):
  number = input("ENTER THE NUMBER : \n")
  numbers.append(number)
numbers_sorted = sorted(numbers)
print  'NUMBERS SORTED IN INCREASING ORDER\n',numbers_sorted
gcd = numbers_sorted[0]

for i in range(1, count):
  divisor = gcd
  dividend = numbers_sorted[i]
  remainder = dividend % divisor
  if remainder == 0 :
  gcd = divisor
  else :
    while not remainder == 0 :
      dividend_one = divisor
      divisor_one = remainder
      remainder = dividend_one % divisor_one
      gcd = divisor_one

print 'GCD OF ' ,count,'NUMBERS IS \n', gcd

5
欢迎使用Stack Overflow!您是否考虑添加一些叙述来解释此代码为何起作用,以及什么使它成为问题的答案?这对提出问题的人以及其他任何人都非常有帮助。
Andrew Barber 2013年

-1

价值互换对我而言效果不佳。因此,我为在<b或a> b中输入的数字设置了类似镜像的情况:

def gcd(a, b):
    if a > b:
        r = a % b
        if r == 0:
            return b
        else:
            return gcd(b, r)
    if a < b:
        r = b % a
        if r == 0:
            return a
        else:
            return gcd(a, r)

print gcd(18, 2)

2
这甚至不是有效的Python语法。缩进很重要。
Marius Gedminas

2
那么当a = b时呢?您应该有一个初始的IF条件才能抓住这一点。
josh.thomson

-2
#This program will find the hcf of a given list of numbers.

A = [65, 20, 100, 85, 125]     #creates and initializes the list of numbers

def greatest_common_divisor(_A):
  iterator = 1
  factor = 1
  a_length = len(_A)
  smallest = 99999

#get the smallest number
for number in _A: #iterate through array
  if number < smallest: #if current not the smallest number
    smallest = number #set to highest

while iterator <= smallest: #iterate from 1 ... smallest number
for index in range(0, a_length): #loop through array
  if _A[index] % iterator != 0: #if the element is not equally divisible by 0
    break #stop and go to next element
  if index == (a_length - 1): #if we reach the last element of array
    factor = iterator #it means that all of them are divisibe by 0
iterator += 1 #let's increment to check if array divisible by next iterator
#print the factor
print factor

print "The highest common factor of: ",
for element in A:
  print element,
print " is: ",

great_common_devisor(A)


-2
def gcdIter(a, b):
gcd= min (a,b)
for i in range(0,min(a,b)):
    if (a%gcd==0 and b%gcd==0):
        return gcd
        break
    gcd-=1

这是最简单的方法...不要加倍努力!
帕BAS

3
感谢您提供可能有助于解决问题的代码,但总的来说,如果答案包括对代码打算做什么以及为什么解决问题的解释,则答案会更有帮助。
神经元

1
这段代码不完整(没有最终的返回语句)并且格式不正确(没有缩进)。我什break至不知道该声明试图实现什么。
kdopen

-2

这是实现以下概念的解决方案Iteration

def gcdIter(a, b):
    '''
    a, b: positive integers

    returns: a positive integer, the greatest common divisor of a & b.
    '''
    if a > b:
        result = b
    result = a

    if result == 1:
        return 1

    while result > 0:
        if a % result == 0 and b % result == 0:
            return result
        result -= 1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.