Python의 최대 공약수 코드 [닫힘]


108

a와 b의 최대 공약수 (GCD)는 나머지없이 둘을 나누는 가장 큰 수입니다.

두 수의 최대 공약수를 찾을 수있는 한 가지 방법은 경우 그 관찰을 기반으로 유클리드 알고리즘이며, r나머지의 부분 인 a으로 나눈 b다음, gcd(a, b) = gcd(b, r). 기본 케이스로 gcd(a, 0) = a.

매개 변수를받는 함수라고 GCD 작성 a하고 b자신의 최대 공약수를 반환합니다.



답변:


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

파이썬 3.5으로 gcd math모듈 ; 의 하나 fractions는 더 이상 사용되지 않습니다. 또한 inspect.getsource더 이상 두 방법에 대한 설명 소스 코드를 반환하지 않습니다.


3
그것은 반환하지 않습니다 "아니오, 나머지 둘 분할하는 _largest_ 번호" 예는, fractions.gcd(1, -1)이다 -1하지만 1 > -1즉, 1분할 모두 1-1이보다 큰없이 나머지와 -1참조 bugs.python.org/issue22477
JFS를

1
@JFSebastian 나는 이것을 문제로 보지 않는다 ... 소스 코드의 주석을보십시오 : "b == 0이 아니면 결과는 b와 같은 부호를 가질gcd(1, -1) == -1 것입니다 " , 따라서 나에게 완전히 합법적 인 것 같습니다.
Marco Bonelli

@MarcoBonelli : 네. 문서화 된대로 작동하지만 대부분의 사람들이 익숙한 교과서 정의는 아닙니다. 위에서 링크 한 토론을 읽으십시오 . 개인적으로 나는있는 그대로를 좋아 fractions.gcd()합니다 (유클리드 링 요소에서 작동합니다).
jfs 2015 년

1
@JFSebastian FWIW (Python 3.5부터) math.gcd(1, -1)1.
Acumenus 2016

1
@ABB math.gcd () 및 fractions.gcd ()는 답변과 주석에서 말한 것처럼 다릅니다.
jfs 2016

39

mn이있는 알고리즘은 매우 오래 실행될 수 있습니다.

이것은 훨씬 더 잘 수행됩니다.

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

5
이것은 표준 라이브러리에도 있습니다.
sayantankhan

10
그 알고리즘은 어떻게 작동합니까? 마법 같네요.
dooderson 2014

20
@netom : 아니요, 할당 은 그렇게수 없습니다 . 튜플 할당은 할당 x되기 전에 사용합니다 . 당신은 할당 yx 처음 그래서 지금, y로 설정 될 것입니다 0(같은 y % y항상 0입니다).
Martijn Pieters

1
@MartijnPieters 예, 맞습니다. 임시 변수를 사용해야했습니다. 다음과 같이 : x_ = y; y = x % y; x = x_
netom 2016

3
@netom :이 답변에서 수행 된 것처럼 튜플 할당을 사용할 때 전혀 필요하지 않습니다.
Martijn Pieters

18

이 버전의 코드는 GCD를 찾기 위해 Euclid의 알고리즘을 사용합니다.

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

28
이름에 iter 를 사용 했지만 실제로는 재귀 버전입니다.
Shiplu Mokaddim

재귀는 루프 버전에 비해 효율성이 낮습니다. + b> a로 호출해야합니다
Dr. Goulu

1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
Andreas K.


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

5
동등성을 비교하려는 경우 'is'를 사용하지 마십시오. 작은 정수 캐시는 CPython 구현 세부 사항입니다.
Marius Gedminas 2013

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

람다를 사용하여

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

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

1
람다 버전은 재귀를 중지 할 조건이 없기 때문에 작동하지 않습니다. 이전에 정의한 함수를 호출하는 것 같습니다.
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)

유클리드의 알고리즘을 기반으로 한 다른 접근 방식입니다.


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

재귀가있는 파이썬에서 :

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>b또는 a<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
파이썬의 스왑 변수는 어린이 놀이 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

-1

가치 교환이 저에게 잘 맞지 않았습니다. 그래서 a <b OR 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
이것은 유효한 파이썬 구문도 아닙니다. 들여 쓰기가 중요합니다.
Marius Gedminas 2013

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: ",

최대 _ 공통 _ 약자 (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

이것이 가장 쉬운 방법입니다 ... 어렵게 만들지 마십시오!
Par bas

3
문제를 해결하는 데 도움이 될 수있는 코드를 제공해 주셔서 감사합니다.하지만 일반적으로 코드의 의도와 문제를 해결하는 이유에 대한 설명이 포함되어 있으면 답변이 훨씬 더 유용합니다.
Neuron

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.