Mã cho dấu phân chia phổ biến nhất bằng Python [đã đóng]


108

Ước chung lớn nhất (GCD) của a và b là số lớn nhất mà chia cả hai mà không có dư.

Một cách để tìm GCD của hai số là thuật toán Euclid, dựa trên quan sát rằng nếu rlà phần dư khi achia cho bthì gcd(a, b) = gcd(b, r). Là một trường hợp cơ sở, chúng tôi có thể sử dụng gcd(a, 0) = a.

Viết một hàm gọi là gcd mà sẽ đưa các thông số abvà trả về ước chung lớn nhất của họ.



thử 'np.gcd.reduce' ở đây
uhoh

Câu trả lời:


299

nằm trong thư viện tiêu chuẩn .

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

Mã nguồn từ inspectmô-đun trong 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

Kể từ Python 3.5, gcd nằm trong mathmô-đun ; cái trong fractionskhông dùng nữa. Hơn nữa, inspect.getsourcekhông còn trả về mã nguồn giải thích cho một trong hai phương pháp.


3
Nó không trả lại "số _largest_ mà chia cả trong số họ không có dư" ví dụ, fractions.gcd(1, -1)-1nhưng 1 > -1ví dụ, 1chia cả hai 1-1không có dư và nó lớn hơn -1, xem bugs.python.org/issue22477
JFS

1
@JFSebastian Tôi không thấy đây là vấn đề ... chỉ cần nhìn vào nhận xét trong mã nguồn: "Trừ khi b == 0, kết quả sẽ có cùng dấu với b" , do đó gcd(1, -1) == -1có vẻ hoàn toàn hợp pháp đối với tôi.
Marco Bonelli

@MarcoBonelli: vâng. Nó hoạt động như tài liệu nhưng nó không phải là định nghĩa sách giáo khoa mà hầu hết mọi người đều quen thuộc. Đọc cuộc thảo luận mà tôi đã liên kết ở trên . Cá nhân, tôi thích như vậy fractions.gcd()(nó hoạt động trên các phần tử vòng Euclide).
jfs

1
@JFSebastian FWIW, kể từ Python 3.5, math.gcd(1, -1)trả về 1.
Acumenus

1
@ABB math.gcd () và fraction.gcd () khác nhau như đã nói trong câu trả lời và phần nhận xét.
jfs

39

Các thuật toán với mn có thể chạy rất lâu.

Cái này hoạt động tốt hơn nhiều:

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

5
Đây cũng là một trong những thư viện tiêu chuẩn.
sayantankhan

10
Làm thế nào để thuật toán đó thậm chí hoạt động? nó giống như phép thuật.
dooderson

20
@netom: không, bài tập không thể viết như vậy được; phép gán tuple sử dụng xtrước khi nó được gán. Bạn đã chỉ định ycho x đầu tiên , vì vậy bây giờ ysẽ được đặt thành 0(như y % yluôn luôn là 0).
Martijn Pieters

1
@MartijnPieters vâng, bạn nói đúng, tôi nên sử dụng một biến tạm thời. như thế này: x_ = y; y = x% y; x = x_
netom

3
@netom: không cần thiết khi sử dụng một bài tập nhiều lần như được thực hiện trong câu trả lời này.
Martijn Pieters

18

Phiên bản mã này sử dụng Thuật toán Euclid để tìm GCD.

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

28
Bạn đã sử dụng iter trong tên nhưng nó thực sự là một phiên bản đệ quy.
Shiplu Mokaddim

đệ quy là kém hiệu quả so với các phiên bản loop, + bạn cần phải gọi nó với b> a
Tiến sĩ Goulu

1
def gcd(a, b): if b == 0: return a return gcd(b, a % b)
Andreas K.


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

5
Không bao giờ sử dụng 'is' khi bạn muốn so sánh để bình đẳng. Bộ nhớ cache số nguyên nhỏ là chi tiết triển khai CPython.
Marius Gedminas

2

Giải pháp rất ngắn gọn bằng cách sử dụng đệ quy:

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

1

sử dụng đệ quy ,

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

sử dụng trong khi ,

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

sử dụng lambda,

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

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

1
Phiên bản lambda không thể hoạt động vì nó không có điều kiện để dừng đệ quy. Tôi nghĩ rằng nó chỉ đang gọi hàm được xác định trước đó của bạn.
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)

Một cách tiếp cận khác dựa trên thuật toán euclid.


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)

0

trong python với đệ quy:

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

Tôi nghĩ một cách khác là sử dụng đệ quy. Đây là mã của tôi:

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

Bạn sẽ không quay lại sau các cuộc gọi đệ quy ... hãy thử chạy gcd(10,5)...
Tomerikoo 27/07/19

0

Đối với 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

Đối với một trong hai a>bhoặc 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 trong python là trẻ em chơi: b, a = a, b. cố gắng đọc thêm về ngôn ngữ
Jason Hu

3
Tôi giống như những gì bạn nói, nhưng tôi không thích cách bạn nói nó
JackyZhu

0

Tôi đã phải làm một cái gì đó như thế này cho một bài tập về nhà bằng cách sử dụng vòng lặp while. Không phải là cách hiệu quả nhất, nhưng nếu bạn không muốn sử dụng một hàm, cách này sẽ hoạt động:

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

Mã này tính toán gcd của nhiều hơn hai số tùy thuộc vào lựa chọn của # người dùng đưa ra, ở đây người dùng đưa ra số

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
Chào mừng bạn đến với Stack Overflow! Bạn có cân nhắc thêm một số câu chuyện để giải thích tại sao mã này hoạt động và điều gì khiến nó trở thành câu trả lời cho câu hỏi? Điều này sẽ rất hữu ích cho người đặt câu hỏi và bất kỳ ai khác đi cùng.
Andrew Barber

-1

Việc hoán đổi giá trị không hoạt động tốt đối với tôi. Vì vậy, tôi chỉ thiết lập một tình huống giống như phản chiếu cho các số được nhập vào a <b HOẶC 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
Đây thậm chí không phải là cú pháp Python hợp lệ. Thụt lề là quan trọng.
Marius Gedminas

2
Còn khi a = b thì sao? bạn nên có điều kiện IF ban đầu để nắm bắt điều này.
josh.thomson

-1

Đây là giải pháp thực hiện khái niệ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

-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

Đây là cách dễ nhất ... Đừng làm khó nó!
Par bas

3
Cảm ơn bạn đã cung cấp mã có thể giúp giải quyết vấn đề, nhưng nhìn chung, các câu trả lời sẽ hữu ích hơn nhiều nếu chúng bao gồm lời giải thích về những gì mã dự định làm và tại sao điều đó giải quyết được vấn đề.
Neuron

1
Mã này không hoàn chỉnh (không có báo cáo trả lại cuối cùng) và được định dạng không đúng (không có bản ghi). Tôi thậm chí không chắc breakcâu nói đó đang cố gắng đạt được điều gì.
kdopen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.