Pythonの最大公約数のコード[終了]


108

aとbの最大公約数(GCD)は、両方を余りなく除算する最大数です。

2つの数の最大公約数を見つけるための一つの方法は、場合という観察に基づいているユークリッドのアルゴリズムであり、r残りの部分であるaことにより、分割されbた後、gcd(a, b) = gcd(b, r)。ベースケースとして使用できますgcd(a, 0) = a

パラメータを取る関数と呼ばGCD書くab、その最大公約数を返します。



回答:


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モジュール内にあります。の1つ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、2015年

@MarcoBonelli:はい。文書化されたとおりに動作しますが、ほとんどの人が精通している教科書の定義ではありません。上記でリンクしたディスカッションを読んでください。個人的には、私はfractions.gcd()そのままです(ユークリッドリング要素で機能します)。
jfs

1
@JFSebastian FWIWは、Python 3.5以降、をmath.gcd(1, -1)返します1
Acumenus 2016年

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前に使用します。firstに割り当てyたので、今度はに設定されます(常に0です)。x y0y % y
Martijn Pieters

1
@MartijnPietersはい、そうです、私は一時変数を使用するべきでした。このように:x_ = y; y = x%y; x = x_
netom 2016年

3
@netom:この回答のようにタプルの割り当てを使用する場合、これはまったく必要ありません。
Martijn Pieters

18

このバージョンのコードは、GCDを見つけるためにユークリッドのアルゴリズムを利用しています。

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

28
名前にiterを使用しましたが、実際には再帰バージョンです。
Shiplu Mokaddim 2016年

再帰はループバージョンに比べて効率が悪い、+ b> aで呼び出す必要がある
Goulu博士

1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
アンドレアスK.


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

5
等しいかどうかを比較する場合は、「is」を使用しないでください。短整数キャッシュは、CPython実装の詳細です。
Marius Gedminas 2013


1

再帰を使用して、

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

使用している間に

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

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

ユークリッドのアルゴリズムに基づく別のアプローチ。


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


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

別の方法は、再帰を使用することだと思います。これが私のコードです:

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

の場合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でvarをスワップすると、子供が遊ぶ: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

このコードは、ユーザーによる選択に応じて、3つ以上の数値の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
これは有効なPython構文ではありません。インデントは重要です。
Marius Gedminas 2013

2
a = bの場合はどうですか?これをキャッチするには、初期IF条件が必要です。
josh.thomson 2015年

-1

これが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

-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

これが最も簡単な方法です...難しくしないでください!
パー浅

3
問題の解決に役立つ可能性のあるコードを提供していただきありがとうございます。一般的に、コードに意図されていることと、それによって問題が解決される理由の説明が含まれていると、回答ははるかに役立ちます。
Neuron

1
このコードは不完全であり(最終的なreturnステートメントなし)、不適切にフォーマットされています(インデントなし)。そのbreak声明が何を成し遂げようとしているのかもよくわかりません。
kdopen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.