web-dev-qa-db-ja.com

複数の数値を持つユークリッドアルゴリズム(GCD)

だから私はPython=で任意の数のGCDを取得するプログラムを書いています。

def GCD(numbers):

    if numbers[-1] == 0:
        return numbers[0]


    # i'm stuck here, this is wrong
    for i in range(len(numbers)-1):
        print GCD([numbers[i+1], numbers[i] % numbers[i+1]])


print GCD(30, 40, 36)

この関数は、数値のリストを取ります。これは2を出力するはずです。ただし、複数の数値を処理できるように、アルゴリズムを再帰的に使用する方法がわかりません。誰か説明できますか?

更新されたが、まだ機能していない:

def GCD(numbers):

    if numbers[-1] == 0:
        return numbers[0]

    gcd = 0

    for i in range(len(numbers)):
        gcd = GCD([numbers[i+1], numbers[i] % numbers[i+1]])
        gcdtemp = GCD([gcd, numbers[i+2]])
        gcd = gcdtemp

    return gcd

わかった、解決した

def GCD(a, b):

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

そして、次のようにreduceを使用します

reduce(GCD, (30, 40, 36))
22

GCDは結合的であるため、GCD(a,b,c,d)GCD(GCD(GCD(a,b),c),d)と同じです。この場合、Pythonの reduce 関数は、len(numbers) > 2のケースを単純な2数値比較に減らすための良い候補です。コードは次のようになります。

_if len(numbers) > 2:
    return reduce(lambda x,y: GCD([x,y]), numbers)
_

Reduceは、リスト内の各要素に指定された関数を適用します。

_gcd = reduce(lambda x,y:GCD([x,y]),[a,b,c,d])
_

することと同じです

_gcd = GCD(a,b)
gcd = GCD(gcd,c)
gcd = GCD(gcd,d)
_

残っているのは、len(numbers) <= 2の場合のコードだけです。 GCDreduceに2つの引数のみを渡すと、関数が最大で1回だけ再帰するようになります(len(numbers) > 2は元の呼び出しでのみ)。スタック。

32
alexkonradi

reduceを使用できます:

>>> from fractions import gcd
>>> reduce(gcd,(30,40,60))
10

これは次と同等です。

>>> lis = (30,40,60,70)
>>> res = gcd(*lis[:2])  #get the gcd of first two numbers
>>> for x in lis[2:]:    #now iterate over the list starting from the 3rd element
...    res = gcd(res,x)

>>> res
10

help on reduce

>>> reduce?
Type:       builtin_function_or_method
reduce(function, sequence[, initial]) -> value

Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
27

[〜#〜] lcm [〜#〜]の3つ以上の数字を見つけるための解決策[〜#〜] python [〜#〜]は次のとおりです。

#finding LCM (Least Common Multiple) of a series of numbers

def GCD(a, b):
    #Gives greatest common divisor using Euclid's Algorithm.
    while b:      
        a, b = b, a % b
    return a

def LCM(a, b):
    #gives lowest common multiple of two numbers
    return a * b // GCD(a, b)

def LCMM(*args):
    #gives LCM of a list of numbers passed as argument 
    return reduce(LCM, args)

ここでは、関数自体がゼロ(0)からn-1で始まるため、range()関数の最後の引数に+1を追加しました。 range() functionの詳細を知るには、ハイパーリンクをクリックしてください。

print ("LCM of numbers (1 to 5) : " + str(LCMM(*range(1, 5+1))))
print ("LCM of numbers (1 to 10) : " + str(LCMM(*range(1, 10+1))))
print (reduce(LCMM,(1,2,3,4,5)))

pythonが初めての人は、与えられたリンクで reduce() 関数についてもっと読むことができます。

3
sarfarazit08

GCD演算子は可換および結合です。この意味は

_gcd(a,b,c) = gcd(gcd(a,b),c) = gcd(a,gcd(b,c))
_

したがって、2つの番号に対してそれを行う方法がわかれば、任意の番号に対して行うことができます


2つの数値に対してこれを行うには、ユークリッドの公式を実装する必要があります。

_// Ensure a >= b >= 1, flip a and b if necessary
while b > 0
  t = a % b
  a = b
  b = t
end
return a
_

その関数をeuclid(a,b)と定義します。次に、gcd(nums)を次のように定義できます。

_if (len(nums) == 1)
  return nums[1]
else
  return euclid(nums[1], gcd(nums[:2]))
_

これは、gcd()の関連プロパティを使用して答えを計算します

3
torquestomp

Pythonでそれを解決する私の方法。それが役に立てば幸い。

def find_gcd(arr):
    if len(arr) <= 1:
        return arr
    else:
        for i in range(len(arr)-1):
            a = arr[i]
            b = arr[i+1]
            while b:
                a, b = b, a%b
            arr[i+1] = a
        return a
def main(array):
    print(find_gcd(array))

main(array=[8, 18, 22, 24]) # 2
main(array=[8, 24]) # 8
main(array=[5]) # [5]
main(array=[]) # []

私がそれを理解する方法のいくつかのダイナミクス:

例:[8、18]-> [18、8]-> [8、2]-> [2、0]

18 = 8x + 2 =(2y)x + 2 = 2zここで、z = xy + 1

例:[18、22]-> [22、18]-> [18、4]-> [4、2]-> [2、0]

22 = 18w + 4 =(4x + 2)w + 4 =((2y)x + 2)w + 2 = 2z

0
Zoe L

次のようにGCD()を呼び出してみてください。

i = 0
temp = numbers[i]
for i in range(len(numbers)-1):
        temp = GCD(numbers[i+1], temp)
0
Deepu