Code für den größten gemeinsamen Teiler in Python [geschlossen]

108

Der größte gemeinsame Teiler (GCD) von a und b ist die größte Zahl, die beide ohne Rest teilt.

Eine Möglichkeit, die GCD zweier Zahlen zu ermitteln, ist der Euklid-Algorithmus, der auf der Beobachtung basiert, dass wenn rder Rest aist , wenn durch geteilt wird b, dann gcd(a, b) = gcd(b, r). Als Basisfall können wir verwenden gcd(a, 0) = a.

Schreiben Sie eine Funktion namens gcd , die Parameter nimmt aund bund gibt ihren größten gemeinsamen Teiler.

Luke D.
quelle
versuche `np.gcd.reduce ' hier
uhoh

Antworten:

300

Es ist in der Standardbibliothek .

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

Quellcode aus dem inspectModul in 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

Ab Python 3.5 gcd befindet sich im mathModul ; der in fractionsist veraltet. Außerdem wird inspect.getsourcefür beide Methoden kein erklärender Quellcode mehr zurückgegeben.

user545424
quelle
3
Dabei spielt es keine Rückkehr „die _largest_ Zahl dass dividieren beide ohne Rest“ zB fractions.gcd(1, -1)ist -1aber 1 > -1dh 1teilen beide 1und -1ohne Rest und es ist größer als -1siehe bugs.python.org/issue22477
JFS
1
@JFSebastian Ich sehe dies nicht als Problem ... sehen Sie sich nur den Kommentar im Quellcode an: "Wenn b == 0 ist, hat das Ergebnis das gleiche Vorzeichen wie b" , daher gcd(1, -1) == -1scheint es mir völlig legitim zu sein.
Marco Bonelli
@ MarcoBonelli: Ja. Es verhält sich wie dokumentiert, aber es ist nicht die Lehrbuchdefinition, mit der die meisten Menschen vertraut sind. Lesen Sie die Diskussion, die ich oben verlinkt habe . Persönlich mag ich wie es fractions.gcd()ist (es funktioniert auf euklidischen Ringelementen).
JFS
1
@JFSebastian FWIW math.gcd(1, -1)kehrt ab Python 3.5 zurück 1.
Acumenus
1
@ABB math.gcd () und Fraktionen.gcd () unterscheiden sich, wie in der Antwort und den Kommentaren angegeben.
JFS
39

Die Algorithmen mit mn können furchtbar lange laufen.

Dieser ist viel besser:

def gcd(x, y):
    while y != 0:
        (x, y) = (y, x % y)
    return x
netom
quelle
5
Dies ist auch die in der Standardbibliothek.
Sayantankhan
10
Wie funktioniert dieser Algorithmus überhaupt? Es ist wie Magie.
Dooderson
20
@netom: nein, die aufgabe kann nicht so geschrieben werden; Die Tupelzuweisung wird verwendet, xbevor sie zugewiesen wird. Sie zugewiesen yzu x ersten , so dass nun ybis zu setzen wird 0(wie y % yimmer 0).
Martijn Pieters
1
@MartijnPieters Ja, Sie haben Recht, ich hätte eine temporäre Variable verwenden sollen. so: x_ = y; y = x% y; x = x_
netom
3
@netom: Wird bei Verwendung einer Tupelzuweisung wie in dieser Antwort überhaupt nicht benötigt.
Martijn Pieters
18

Diese Codeversion verwendet den Euklid-Algorithmus zum Auffinden von GCD.

def gcd_recursive(a, b):
    if b == 0:
        return a
    else:
        return gcd_recursive(b, a % b)
Ankush
quelle
28
Sie haben iter im Namen verwendet, aber es ist tatsächlich eine rekursive Version.
Shiplu Mokaddim
Rekursion ist im Vergleich zu Schleifenversionen schlecht effizient, + Sie müssen es mit b> a
Dr. Goulu
1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
Andreas K.
15
gcd = lambda m,n: m if not n else gcd(n,m%n)
Jonas Byström
quelle
2
def gcd(m,n):
    return gcd(abs(m-n), min(m, n)) if (m-n) else n
Dansalmo
quelle
5
Verwenden Sie niemals 'ist', wenn Sie für Gleichheit vergleichen möchten. Der Cache für kleine Ganzzahlen ist ein CPython-Implementierungsdetail.
Marius Gedminas
2

Sehr prägnante Lösung mit Rekursion:

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a%b)
Preetika Mondal
quelle
1

mit Rekursion ,

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

mit while ,

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

mit Lambda,

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

>>> gcd(10,20)
>>> 10
Mohideen bin Mohammed
quelle
1
Die Lambda-Version kann nicht funktionieren, da sie keine Bedingung zum Stoppen der Rekursion enthält. Ich denke, es ruft nur Ihre zuvor definierte Funktion auf.
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)

Ein anderer Ansatz basierend auf dem Euklid-Algorithmus.


quelle
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)
Täuschungen
quelle
0

in Python mit Rekursion:

def gcd(a, b):
    if a%b == 0:
        return b
    return gcd(b, a%b)
Keajer
quelle
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
quelle
0

Ich denke, ein anderer Weg ist die Verwendung von Rekursion. Hier ist mein Code:

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
quelle
Sie kehren nach den rekursiven Aufrufen nicht zurück ... versuchen Sie es mit Laufen gcd(10,5)...
Tomerikoo
0

Für 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

Für entweder a>boder 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
quelle
4
Swap Vars in Python ist Kinderspiel : b, a = a, b. versuchen Sie mehr über die Sprache zu lesen
Jason Hu
3
Ich mag, was Sie sagen, aber ich mag nicht, wie Sie es sagen
JackyZhu
0

Ich musste so etwas für eine Hausaufgabe mit while-Schleifen machen. Nicht der effizienteste Weg, aber wenn Sie keine Funktion verwenden möchten, funktioniert dies:

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
quelle
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
quelle
-1

Dieser Code berechnet die gcd von mehr als zwei Zahlen in Abhängigkeit von der Auswahl durch # den Benutzer, hier gibt der Benutzer die Zahl an

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
quelle
5
Willkommen bei Stack Overflow! Würden Sie eine Erzählung hinzufügen, um zu erklären, warum dieser Code funktioniert und was ihn zu einer Antwort auf die Frage macht? Dies wäre sehr hilfreich für die Person, die die Frage stellt, und für alle anderen, die mitkommen.
Andrew Barber
-1

Der Wertetausch hat bei mir nicht gut funktioniert. Also habe ich einfach eine spiegelähnliche Situation für Zahlen eingerichtet, die entweder in a <b ODER a> b eingegeben werden:

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
quelle
2
Dies ist nicht einmal eine gültige Python-Syntax. Einrückung ist wichtig.
Marius Gedminas
2
Was ist, wenn a = b? Sie sollten eine anfängliche IF-Bedingung haben, um dies zu erfassen.
Josh.thomson
-1

Hier ist die Lösung, die das Konzept implementiert 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
quelle
-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: ",

größter_Gemeinsamer Berater (A)

user4713071
quelle
-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
quelle
Dies ist der einfachste Weg ... Mach es dir nicht schwer!
Par bas
3
Vielen Dank für die Bereitstellung von Code, der zur Lösung des Problems beitragen kann. Im Allgemeinen sind Antworten jedoch viel hilfreicher, wenn sie eine Erklärung enthalten, was der Code tun soll und warum das Problem dadurch gelöst wird.
Neuron
1
Dieser Code ist unvollständig (keine endgültige Rückgabeanweisung) und nicht ordnungsgemäß formatiert (kein Einzug). Ich bin mir nicht einmal sicher, was diese breakAussage erreichen soll.
kdopen