Kode untuk Pembagi Umum Terbesar dengan Python [tertutup]


108

Pembagi persekutuan terbesar (PBT) dari a dan b adalah bilangan terbesar yang membagi keduanya tanpa sisa.

Salah satu cara untuk mencari PBK dari dua angka adalah algoritma Euclid, yang didasarkan pada pengamatan bahwa jika radalah sisa jika adibagi b, maka gcd(a, b) = gcd(b, r). Sebagai kasus dasar, kita bisa menggunakan gcd(a, 0) = a.

Tulis fungsi yang disebut gcd yang mengambil parameter adan bdan mengembalikan pembagi persekutuan terbesarnya.



coba `np.gcd.reduce 'di sini
uhoh

Jawaban:


300

Ada di perpustakaan standar .

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

Kode sumber dari inspectmodul di Python 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

Pada Python 3.5, gcd ada di mathmodul ; yang di fractionssudah usang. Selain itu, inspect.getsourcetidak lagi mengembalikan kode sumber penjelasan untuk metode mana pun.


3
Itu tidak mengembalikan "nomor _largest_ yang membagi keduanya tanpa sisa" misalnya, fractions.gcd(1, -1)adalah -1tetapi 1 > -1, 1membagi keduanya 1dan -1tanpa sisa dan lebih besar dari -1, lihat bugs.python.org/issue22477
jfs

1
@JFSebastian Saya tidak melihat ini sebagai masalah ... lihat saja komentar di kode sumber: "Kecuali b == 0, hasilnya akan memiliki tanda yang sama dengan b" , oleh karena itu gcd(1, -1) == -1tampaknya benar-benar sah bagi saya.
Marco Bonelli

@MarcoBonelli: ya. Ini berperilaku seperti yang didokumentasikan tetapi itu bukan definisi buku teks yang kebanyakan orang kenal. Baca pembahasan yang saya tautkan di atas . Secara pribadi, saya suka fractions.gcd()apa adanya (ini berfungsi pada elemen cincin Euclidean).
jfs

1
@JFSebastian FWIW, pada Python 3.5, math.gcd(1, -1)kembali 1.
Acumenus

1
@ABB math.gcd () dan fractions.gcd () berbeda seperti yang dikatakan dalam jawaban dan komentar.
jfs

39

Algoritme dengan mn bisa berjalan sangat lama.

Yang ini bekerja jauh lebih baik:

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

5
Ini juga yang ada di perpustakaan standar.
sayantankhan

10
Bagaimana cara kerja algoritma itu? itu seperti sihir.
dooderson

20
@netom: tidak, tugas tidak dapat ditulis seperti itu; tugas tupel digunakan xsebelum ditugaskan. Anda ditetapkan yke x pertama , jadi sekarang yakan disetel ke 0(seperti y % ybiasa 0).
Martijn Pieters

1
@MartijnPieters ya, Anda benar, saya seharusnya menggunakan variabel sementara. seperti ini: x_ = y; y = x% y; x = x_
netom

3
@netom: yang tidak diperlukan sama sekali saat menggunakan tugas tuple seperti yang dilakukan dalam jawaban ini.
Martijn Pieters

18

Versi kode ini menggunakan Algoritma Euclid untuk menemukan GCD.

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

28
Anda menggunakan iter pada namanya tetapi sebenarnya ini adalah versi rekursif.
Shiplu Mokaddim

rekursi kurang efisien dibandingkan dengan versi loop, + Anda perlu menyebutnya dengan 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
Jangan pernah gunakan 'adalah' saat Anda bermaksud membandingkan kesetaraan. Cache bilangan bulat kecil adalah detail implementasi CPython.
Marius Gedminas

2

Solusi yang sangat ringkas menggunakan rekursi:

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

2

menggunakan rekursi ,

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

menggunakan sementara ,

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

menggunakan lambda,

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

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

1
Versi lambda tidak dapat berfungsi karena tidak memiliki kondisi untuk menghentikan rekursi. Saya pikir itu hanya memanggil fungsi yang Anda tentukan sebelumnya.
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)

Pendekatan berbeda berdasarkan algoritma 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

Saya pikir cara lain adalah dengan menggunakan rekursi. Ini kode saya:

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

Anda tidak kembali setelah panggilan rekursif ... coba jalankan gcd(10,5)...
Tomerikoo

0

dengan python dengan rekursi:

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

Untuk 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

Untuk salah satu a>batau 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
Swap vars di python adalah anak-anak bermain: b, a = a, b. coba baca lebih lanjut tentang bahasanya
Jason Hu

3
Saya suka apa yang Anda katakan, tapi saya tidak suka cara Anda mengatakannya
JackyZhu

0

Saya harus melakukan sesuatu seperti ini untuk tugas pekerjaan rumah menggunakan while loop. Bukan cara yang paling efisien, tetapi jika Anda tidak ingin menggunakan suatu fungsi, ini berfungsi:

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

Kode ini menghitung gcd lebih dari dua angka tergantung pada pilihan yang diberikan oleh pengguna, di sini pengguna memberikan nomor tersebut

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
Selamat datang di Stack Overflow! Apakah Anda akan mempertimbangkan untuk menambahkan beberapa narasi untuk menjelaskan mengapa kode ini berfungsi, dan apa yang membuatnya menjadi jawaban atas pertanyaan? Ini akan sangat membantu orang yang mengajukan pertanyaan, dan siapa pun yang datang.
Andrew Barber

-1

Pertukaran nilai tidak bekerja dengan baik untuk saya. Jadi saya hanya mengatur situasi seperti cermin untuk angka yang dimasukkan baik dalam 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
Ini bahkan bukan sintaks Python yang valid. Indentasi itu penting.
Marius Gedminas

2
Bagaimana jika a = b? Anda harus memiliki kondisi IF awal untuk menangkapnya.
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: ",

pembimbing_komunitas_besar (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

Ini adalah cara termudah ... Jangan mempersulit!
Par bas

3
Terima kasih telah memberikan kode yang dapat membantu memecahkan masalah, tetapi umumnya, jawaban jauh lebih membantu jika menyertakan penjelasan tentang tujuan kode, dan mengapa hal itu menyelesaikan masalah.
Neuron

1
Kode ini tidak lengkap (tidak ada pernyataan pengembalian akhir) dan tidak diformat dengan benar (tidak ada indentaion). Saya bahkan tidak yakin breakpernyataan apa yang ingin dicapai.
kdopen

-2

Berikut solusi yang menerapkan konsep 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.