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.

Luke D
sumber

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.

pengguna545424
sumber
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
netom
sumber
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)
Ankush
sumber
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.
16
gcd = lambda m,n: m if not n else gcd(n,m%n)
Jonas Byström
sumber
3
def gcd(m,n):
    return gcd(abs(m-n), min(m, n)) if (m-n) else n
dansalmo
sumber
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)
preetika mondal
sumber
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
Mohideen bin Mohammed
sumber
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.


sumber
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)
MALU
sumber
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
dexhunter
sumber
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)
keajer
sumber
0
def gcd(a,b):
    if b > a:
        return gcd(b,a)
    r = a%b
    if r == 0:
        return b
    return gcd(r,b)
dpeleg2000.dll
sumber
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
Rao Baswaraj
sumber
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])
Vanessa
sumber
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))
Sai prateek
sumber
-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
Prashant
sumber
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)
troychroi.dll
sumber
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)

pengguna4713071
sumber
-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
sumber
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
Bikramjeet Singh
sumber