Python'daki En Büyük Ortak Bölen için Kod [kapalı]


108

A ve b'nin en büyük ortak böleni (OBEB), ikisini hiç kalan olmadan bölen en büyük sayıdır.

İki sayının OBEB'ini bulmanın bir yolu, Öklid'in algoritmasıdır; bu, şu gözlemi temel alır: eğer rgeri kalan a, bölündüğünde b, o zaman gcd(a, b) = gcd(b, r). Temel durum olarak kullanabiliriz gcd(a, 0) = a.

Parametreleri alan ave ben büyük ortak bölenini döndüren gcd adında bir işlev yazın .



Yanıtlar:


300

Bu var standart kütüphanede .

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

inspectPython 2.7'deki modülden kaynak kodu :

>>> 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 itibariyle gcd ise mathmodül ; içindeki biri fractionskullanımdan kaldırıldı. Ayrıca, inspect.getsourceartık her iki yöntem için de açıklayıcı kaynak kodu döndürmez.


3
O dönmez "hayır kalanı ikisinin de böler o _largest_ numarası" örneğin fractions.gcd(1, -1)olduğunu -1ancak 1 > -1yani 1böler hem 1ve -1bunun daha büyük hiçbir kalanı ve -1bkz bugs.python.org/issue22477
jfs

1
@JFSebastian Bunu bir sorun olarak görmüyorum ... sadece kaynak kodundaki yoruma bakın: "b == 0 olmadığı sürece, sonuç b ile aynı işarete sahip olacaktır" , bu yüzden gcd(1, -1) == -1bana tamamen yasal görünüyor.
Marco Bonelli

@MarcoBonelli: evet. Belgelendiği gibi davranır, ancak çoğu insanın aşina olduğu ders kitabı tanımı değildir. Yukarıda bağlantılandırdığım tartışmayı okuyun . Şahsen ben olduğu gibi seviyorum fractions.gcd()(Öklid halka unsurları üzerinde çalışıyor).
jfs

1
@JFSebastian FWIW, Python 3.5 itibariyle math.gcd(1, -1)geri dönüyor 1.
Acumenus

1
@ABB math.gcd () ve fractions.gcd () yanıtta ve yorumlarda belirtildiği gibi farklıdır.
jfs

39

Mn ile algoritmalar çok uzun süre çalışabilir.

Bu çok daha iyi performans gösteriyor:

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

5
Bu aynı zamanda standart kütüphanede olanıdır.
sayantankhan

10
Bu algoritma nasıl çalışıyor? sihir gibi.
dooderson

20
@netom: hayır, atama olamaz böyle yazılır; demet ataması atanmadan xönce kullanır . Atanan yiçin x ilk şimdi, yayarlı olacak 0(aynı y % yzaman 0'dır).
Martijn Pieters

1
@MartijnPieters evet, haklısınız, geçici bir değişken kullanmalıydım. bunun gibi: x_ = y; y = x% y; x =
x_

3
@netom: Bu cevapta yapıldığı gibi bir demet ataması kullanırken hiç gerekli değildir.
Martijn Pieters

18

Kodun bu sürümü, GCD'yi bulmak için Euclid Algoritmasını kullanır.

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

28
Adında iter kullandınız ama aslında yinelemeli bir versiyonu.
Shiplu Mokaddim 01

özyineleme, döngü sürümleriyle karşılaştırıldığında yetersiz verimlidir, + bunu b> a ile çağırmanız gerekir
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
Eşitliği karşılaştırmak istediğinizde asla 'eşittir' kullanmayın. Küçük tamsayılar önbelleği bir CPython uygulama detayıdır.
Marius Gedminas

2

Özyineleme kullanarak çok kısa bir çözüm:

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

2

özyineleme kullanarak ,

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

while kullanarak ,

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

lambda kullanarak,

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

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

1
Lambda sürümü, özyinelemeyi durdurmak için bir koşulu olmadığından çalışamaz. Sanırım sadece önceden tanımladığınız işlevi çağırıyor.
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)

Öklid algoritmasına dayalı farklı bir yaklaşım.


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

Bence başka bir yol da özyinelemeyi kullanmak. İşte kodum:

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

Yinelemeli aramalardan sonra geri gcd(10,5)
dönmüyorsunuz

0

python'da özyinelemeli:

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

Şunun için 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

Ya a>bveya için 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
takas python çocukların oyun olduğunu vars: b, a = a, b. dil hakkında daha fazlasını okumaya çalışın
Jason Hu

3
Söylediklerini beğendim ama söylemeni
beğenmedim

0

While döngülerini kullanarak bir ev ödevi için buna benzer bir şey yapmak zorunda kaldım. En verimli yol değil, ancak bir işlevi kullanmak istemiyorsanız bu çalışır:

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

Bu kod, # kullanıcı tarafından verilen seçime bağlı olarak ikiden fazla sayının gcd'sini hesaplar, burada kullanıcı numarayı verir

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'a hoş geldiniz! Bu kodun neden çalıştığını ve onu sorunun cevabı yapan şeyin ne olduğunu açıklamak için biraz açıklama eklemeyi düşünür müsünüz? Bu, soruyu soran kişiye ve karşısına çıkan herkese çok yardımcı olacaktır.
Andrew Barber

-1

Değer değişimi benim için pek işe yaramadı. Dolayısıyla, a <b VEYA a> b'ye girilen sayılar için aynaya benzer bir durum oluşturdum:

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
Bu geçerli bir Python sözdizimi bile değil. Girinti önemlidir.
Marius Gedminas

2
Ne zaman a = b? Bunu yakalamak için ilk EĞER koşuluna sahip olmalısınız.
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

Bu en kolay yol ... Bunu zorlaştırma!
Par bas

3
Sorunun çözülmesine yardımcı olabilecek kod sağladığınız için teşekkür ederiz, ancak genel olarak yanıtlar, kodun ne yapması amaçlandığına ve bunun neden sorunu çözdüğüne dair bir açıklama içeriyorsa çok daha yararlıdır.
Neuron

1
Bu kod eksiktir (son dönüş ifadesi yok) ve yanlış biçimlendirilmiş (girinti yok). Bu breakifadenin neyi başarmaya çalıştığından bile emin değilim .
kdopen

-2

İşte konseptini uygulayan çözüm 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.