Python で最大公約数を見つけるための 5 つの一般的な方法

最大公約数を見つけることは、比較的一般的な種類の演習です. 次のエディターでは、さらに 5 つの一般的なアルゴリズムが提供されます. 親指を立てることを忘れないでください!

一般的に言えば、最大公約数を見つける方法は約 5 つあります。

方法 1: ショート ディビジョン

        短縮除算は最大公約数を求める方法で、最小公倍数を求めるためにも使用できます。いくつかの数の最大公約数を見つける方法は、観察と比較の方法から始まります。つまり、最初に各数の約数を見つけ、次に共通約数を見つけ、最後に共通の最大公約数を見つけます。要因。その後、素因数を分解する方法を使用して、2 つの数の因数を別々に分解し、演算を実行しました。その後、ショートディビジョンに進化しました。短除算の演算方法は、最初に除数をそれで割り切れる素数で除算し、2 つの数の商が素数になるまで繰り返します。

        簡単に言えば、2 つの数のすべての公約数を段階的に見つけ、これらの公約数を掛け合わせて最大公約数を求めることです。

a=int(input("please input the first number:"))
b=int(input("please input the second number:"))
m,n=a,b #  创建两个变量存储a和b
t=1 #  创建t作为最大公约数的载体
for i in range(2,min(a,b)):
    while (a%i==0 and b%i==0):
       t*=i #  所有公约数累乘起来
       a/=i
       b/=i
print((f"{m},{n}的最大公约数为:{t}"))

        この方法は少し面倒ですが、ロジックは非常に明確で、間違いを犯すことは容易ではありません。

方法 2: ユークリッド アルゴリズム (ローリング アンド ディバイディング法)

        Euclid のアルゴリズムは、2 つの正の整数の最大公約数を求めるアルゴリズムです。古代ギリシャの数学者ユークリッドがこのアルゴリズムを著書「The Elements」で最初に記述したため、ユークリッドのアルゴリズムと名付けられました。      

        2 つの正の整数 1997 と 615 の最大公約数を求める必要がある場合は、ユークリッド アルゴリズムを使用して次のように処理します。

1997 / 615 = 3·······152

615 / 152 = 4······7

152 / 7 = 21······5

7 / 5 = 1······2

5 / 2 = 2······1

2 / 1 = 2······0

        今のところ最大公約数は1

        除数と剰余で除算を繰り返し、剰余が0のとき、現在の式の約数を最大公約数とすると、1997年と615の最大公約数1が得られます。

        ロジックを理解したら、プログラムを書き始めましょう。

a=int(input("please input the first number:"))
b=int(input("please input the second number:"))
#  首先要给两数排序,保证大数除以小数
m=max(a,b)
n=min(a,b)
t=m%n
while t!=0:
    m,n=n,t #  仔细观察不难发现:每个除式的m、n是都是上一个式子的n和余数
    t=m%n #  更新余数
print(f"{a}和{b}的最大公约数为{n}")

        もちろん、再帰的な方法でも Euclid のアルゴリズムを実装できます。

def GCD(a,b):
    #  比较大小,保证大数除以小数
    if a<b:
        a,b=b,a
    #  判断是否能整除,若能整除,直接返回被除数
    if a%b==0:
        return b
    #  若不能整除,则返回函数GCD,参数做相应变化
    else:
        return GCD(b,a%b)
a=int(input("please input the first number:"))
b=int(input("please input the second number:"))
gcd=GCD(a,b)
print(f"{a}和{b}的最大公约数为{gcd}")

方法 3: 相縮小手術

        モアフェーズ減算は「算術九章」から最大公約数を求めるアルゴリズムで、本来は簡約用に設計されたものですが、最大公約数が必要な場合に適しています。元のテキストは次のとおりです。

        半分にできれば半分に、半分にできなければ分母と息子の数を設定し、少ない方で数を減らし、損失を減らし、同じことを求めます。等しい数で近似します。     

現地語訳:

(スコアを分割する必要がある場合) 半分にできる場合は、半分にします (つまり、2 を使用して分割します)。半分にできない場合は、分母と分子の大きさを比較し、大きな数から小数を引き、減数と差が等しくなるまで引き、この等しい数を使って割ります。

        具体的な手順:

ステップ 1: 任意の 2 つの正の整数が与えられた場合、それらが両方とも偶数であるかどうかを判断します。はいの場合は 2 を使用して削減し、そうでない場合は 2 番目のステップに進みます。

ステップ 2: 小さい方の数値を大きい方の数値で引き、結果の差を小さい方の数値と比較し、大きい方の数値を減算します。結果の減数と差が等しくなるまで、この操作を続けます。

次に、最初のステップで削減された 2 のいくつかの積と、2 番目のステップでの平均数の積が、求められる最大公約数です。

ここでいう「同数」は公約数です。「同数」を求める方法が「損切り比較」の方法です。

        ここで、位相縮約法を使用して98 と 63 の最大公約数を見つけます。

解決策: 63 は偶数ではないため、98 と 63 を大きな数で減らし、それらを繰り返し減算します

98-63=35

63-35=28

35-28=7

28-7=21

21-7=14

14-7=7

したがって、98 と 63 の最大公約数は 7 です。

a=int(input("please input the first number:"))
b=int(input("please input the second number:"))
#  首先要给两数排序,保证大数减小数
m=max(a,b)
n=min(a,b)
#  判断两数是否都是偶数,如果都是偶数就同时除2
while m%2==0 and n%2==0:
    m,n=m/2,n/2
t=m-n
#  判断条件是减数和差相等
while n!=t:
    m,n=max(n,t),min(n,t) #  每减一轮之后,都要重新判断减数和差的大小,再次以大数减去小数
    t=m-n
print(f"{a}和{b}的最大公约数为{n}")

方法 4: 網羅的方法 (列挙法)

        2 つの数の小さい方から始めて、小さい方から大きい方へ列挙し、公約数を見つけて、公約数が大きい方の数にも属していることを確認します。これらの公約数の最大のものは最大公約数です。大から小へ、公約数が見つかるまでループから飛び出し、その公約数が最大公約数になります。

a=int(input("please input the first number:"))
b=int(input("please input the second number:"))
p,q=min(a,b),max(a,b)
lst=[]
for i in range(1,p+1):
    if p%i==0 and q%i==0:
        lst.append(i)
gcd=max(lst)
print(f"{a}和{b}的最大公约数为{gcd}")

#a=int(input("please input the first number:"))
#b=int(input("please input the second number:"))
#p,q=min(a,b),max(a,b)
#gcd=0
#for i in range(p,0,-1):
#    if p%i==0 and q%i==0:
#        gcd=i
#        break
#print(f"{a}和{b}的最大公约数为{gcd}")

方法 5: スタイン アルゴリズム

        Stein アルゴリズムは、 2 つの数の最大公約数を計算するためのアルゴリズムですが、ユークリッド アルゴリズムのテストが必要であり、大きな整数を処理すると処理時間が長くなるという欠点を改善したアルゴリズムです。

ユークリッド アルゴリズムの欠陥:

ユークリッド アルゴリズムは、2 つの数値の最大公約数を        計算するための伝統的なアルゴリズムであり、理論的にも実用的にも非常に優れています。しかし、素数が比較的小さいときは一般に感じられず、素数が大きい場合にのみ現れる致命的な欠陥があります。

        (もちろん、128 ビットは許容されます) そのような整数の場合、2 つの数値間のモジュラスを計算するのは非常に簡単です。ワード長が 32 ビットのプラットフォームの場合、 32 ビットを超えない 2 つの整数のモジュラスを計算するのに1命令サイクルしかかからず、64 ビット未満の整数のモジュラスを計算するのに数サイクルしかかかりません。しかし、より大きな素数の場合、そのような計算プロセスはユーザーが設計する必要があります. 64 ビットを超える 2 つの整数のモジュラスを計算するには、マルチの手動計算プロセスと同様の試行錯誤法を使用する必要があります。 -桁除算. このプロセスは複雑であるだけでなく、多くの CPU 時間を消費します。現代の暗号アルゴリズムでは、128 ビットを超える素数を計算する必要があるのが一般的であり、除算とモジュラスを放棄するようなプログラムを設計することが急務です。

次の 2 つの結論を見てください。

        gcd(a,a)=a、つまり、数値の公約数であり、それ自体は依然としてそれ自体です。
        gcd(ka,kb)=k gcd(a,b) つまり、最大公約数演算と乗算演算を入れ替えることができます。特に、k=2 の場合、2 つの偶数の最大公約数は 2 で割り切れなければならないことを意味します。

        k と b が互いに素数の場合、gcd(ka,b)=gcd(a,b)、つまり、最大公約数に影響を与えることなく、2 つの数のうちの 1 つのみに含まれる約数が削減されます。特に、k=2の場合、偶数と奇数の最大公約数を計算する場合、偶数を先に2で割り切れることを意味する。

        :param a: 最初の数字

        :param b: 2 番目の数値

        :return: 最大公約数

def gcd_Stein(a, b):
    #  保证b比a小
    if a < b:
        a, b = b, a
    if (0 == b):
        return a
    #  a、b都是偶数,除2右移一位即可
    if a % 2 == 0 and b % 2 == 0:
        return 2 * gcd_Stein(a / 2, b / 2)
    #  a是偶数
    if a % 2 == 0:
        return gcd_Stein(a / 2, b)
    #  b是偶数
    if b % 2 == 0:
        return gcd_Stein(a, b / 2)
    #  都是奇数
    return gcd_Stein((a + b) / 2, (a - b) / 2)

a=int(input("please input the first number:"))
b=int(input("please input the second number:"))
gcd=int(gcd_Stein(a,b))
print(f"{a}和{b}的最大公约数为{gcd}")

上記は、編集者によってまとめられた5つの一般的に使用される方法です。参考になれば幸いです。それを好きになることを忘れないでください!

おすすめ

転載: blog.csdn.net/m0_69265664/article/details/125708828