Код найбільшого спільного дільника в Python [закрито]


108

Найбільший спільний дільник (GCD) на a і b - найбільше число, яке ділить їх обох без залишку.

Одним із способів знайти GCD двох чисел є алгоритм Евкліда, який базується на спостереженні, що якщо rзалишок, коли aділиться на b, то gcd(a, b) = gcd(b, r). В якості базового випадку ми можемо використовувати gcd(a, 0) = a.

Напишіть функцію під назвою НСД , який приймає параметри aі bнаступним поверненням їх найбільший спільний дільник.



спробуйте `np.gcd.reduce ' тут
— uhoh

Відповіді:


300

Це в стандартній бібліотеці .

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

Вихідний код з inspectмодуля в 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

Станом на Python 3.5, gcd знаходиться в mathмодулі ; той, що знаходиться 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мені здається абсолютно законним.
— Марко Бонеллі

@MarcoBonelli: так. Він поводиться як задокументований, але більшість людей не знайомі з визначенням підручника. Прочитайте дискусію, яку я зв'язав вище . Особисто мені подобається, fractions.gcd()як є (це працює на елементах евклідового кільця).
— jfs

1
@JFSebastian FWIW, станом на Python 3.5, math.gcd(1, -1)повертається 1.
— Acumenus

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

10
Як цей алгоритм навіть працює? це як магія.
— dooderson

20
@netom: ні, завдання не можна писати так; призначення кортежу використовується xдо його призначення. Ви призначені yна x перший , так що тепер yзбирається бути встановлений 0(як y % yзавжди 0).
— Martijn Pieters

1
@MartijnPieters так, ти маєш рацію, я повинен був використовувати тимчасову змінну. ось так: x_ = y; y = x% y; x = x_
— netom

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 в назві, але насправді це рекурсивна версія.
— Шиплу Мокаддім

рекурсія є малоефективною порівняно з версіями циклу, + вам потрібно викликати це b> a
— д-р Goulu

1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
— Андреас К.


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

5
Ніколи не використовуйте "є", коли ви маєте на увазі порівняння для рівності. Кеш малих цілих чисел - це деталь реалізації CPython.
— Маріус Гедмінас

2

Дуже стисле рішення з використанням рекурсії:

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

2

використовуючи рекурсію ,

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
Версія лямбда не може працювати, оскільки вона не має умови для зупинки рекурсії. Я думаю, що це просто виклик вашої раніше визначеної функції.
— рем

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)

Інший підхід, заснований на алгоритмі еукліда.


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

Я думаю, що інший спосіб - використовувати рекурсію. Ось мій код:

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>bабо 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
своп вари в Пітоні діти грають: b, a = a, b. спробуйте прочитати більше про мову
— Джейсон Ху

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

Цей код обчислює 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
Ласкаво просимо до переповнення стека! Чи можете ви додати трохи розповіді, щоб пояснити, чому цей код працює, і що робить його відповіддю на питання? Це було б дуже корисно для людини, яка задає це питання, і будь-кому іншому, хто йде разом.
— Ендрю Барбер

-1

Переміщення значень не спрацювало добре для мене. Тому я просто створив дзеркальну ситуацію для чисел, які вводяться або в <b АБО> 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. Відступ важливий.
— Маріус Гедмінас

2
Що робити, коли a = b? у вас має бути початкова умова, якщо це зробити.
— 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: ",

найбільший_коммон_девізор (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

Це найпростіший спосіб ... Не ускладнюйте!
— Par bas

3
Дякуємо за надання коду, який може допомогти вирішити проблему, але, як правило, відповіді набагато корисніші, якщо вони містять пояснення того, що призначений для цього коду та чому це вирішує проблему.
— Нейрон

1
Цей код є неповним (немає остаточного твердження про повернення) та неправильно відформатованим (без відступу). Я навіть не впевнений, чого breakнамагається досягти це твердження.
— хтопен

-2

Ось рішення, що реалізує концепцію 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.