web-dev-qa-db-ja.com

n個の数字のgcdを見つける最も速い方法は何ですか?

n数の最大公約数を計算する最速の方法は何ですか?

35

LehmerのGCDアルゴリズム を使用する必要があります。

3
akjlab

再帰なし:

int result = numbers[0];
for(int i = 1; i < numbers.length; i++){
    result = gcd(result, numbers[i]);
}
return result;

非常に大きな配列の場合、fork-joinパターンを使用すると、配列を分割してgcdを並列に計算する方が高速になる場合があります。疑似コードは次のとおりです。

int calculateGCD(int[] numbers){
    if(numbers.length <= 2){
        return gcd(numbers);    
    }
    else {
        INVOKE-IN-PARALLEL {
            left = calculateGCD(extractLeftHalf(numbers));
            right = calculateGCD(extractRightHalf(numbers));
        }
        return gcd(left,right);
    }
}
17
dogbane

最初に数値をソートし、最小の2つの数値から再帰的にgcdを計算することができます。

15
lhf

C++ 17

C++の組み込み__gcd(int a, int b)関数を使用して、n個の数値のgcdを計算するこの関数を作成しました。

int gcd(vector<int> vec, int vsize)
{
    int gcd = vec[0];
    for (int i = 1; i < vsize; i++)
    {
        gcd = __gcd(gcd, vec[i]);
    }
    return gcd;
}

この関数の詳細については、 this link をご覧ください。

次のリンクから DijkstraのGCDアルゴリズム も参照してください。分割なしで動作します。そのため、少し速くなる可能性があります(間違っている場合は修正してください)。

減算によるユークリッドアルゴリズムを使用した次の方法はどうですか。

function getGCD(arr){
    let min = Math.min(...arr); 
    let max= Math.max(...arr);
    if(min==max){
        return min;
    }else{
         for(let i in arr){
            if(arr[i]>min){
                arr[i]=arr[i]-min;
            }
        }
        return getGCD(arr);
    }
   
}

console.log(getGCD([2,3,4,5,6]))

上記の実装にはO(n ^ 2)時間かかります。実装可能な 改善 がありますが、これらをn個の番号で試すことはできませんでした。

1
sam's

ユークリッドアルゴリズムを使用します。

function gcd(a, b)
while b ≠ 0
   t := b; 
   b := a mod b; 
   a := t; 
return a;

最初の2つの数値に適用し、次に3番目の数値に結果を適用します。

read(a);
read(b);

result := gcd(a, b);
i := 3;
while(i <= n){
    read(a)
    result := gcd(result, a);
}
print(result);
1
Nagy Robi

分割征服を使用できます。 gcdN([])を計算するには、リストを前半と後半に分割します。リストごとにnumが1つしかない場合。 gcd2(n1、n2)を使用して計算します。

簡単なサンプルコードを作成しました。 (リスト内のすべてのnumが正の整数であると仮定)

def gcdN(nums):
    n = len(nums)
    if n == 0: return "ERROR"
    if n == 1: return nums[0]
    if n >= 2: return gcd2(gcdN(nums[:n//2]), gcdN(nums[n//2:]))

def gcd2(n1, n2):
    for num in xrange(min(n1, n2), 0, -1):
        if n1 % num == 0 and n2 % num == 0:
            return num
1
CSY

a lot of smallの数がある場合、因数分解は実際には高速です。

//Java
int[] array = {60, 90, 45};
int gcd = 1;
outer: for (int d = 2; true; d += 1 + (d % 2)) {
    boolean any = false;
    do {
        boolean all = true;
        any = false;
        boolean ready = true;
        for (int i = 0; i < array.length; i++) {
            ready &= (array[i] == 1);
            if (array[i] % d == 0) {
                any = true;
                array[i] /= d;
            } else all = false;
        }
        if (all) gcd *= d;
        if (ready) break outer;
    } while (any);
}
System.out.println(gcd);

(いくつかの例で動作しますが、実際にはテストされていません)

1
Landei
//Recursive solution to get the GCD of Two Numbers

long long int gcd(long long int a,long long int b)<br>
{
   return b==0 ? a : gcd(b,a%b);
}
int main(){
  long long int a,b;
  cin>>a>>b;
  if(a>b) cout<<gcd(a,b);
  else cout<<gcd(b,a);
return 0;
}
0
Mohit Kumra

以下は、配列を使用してN個の数値のHCFを見つけるためのCプログラムのソースコードです。

#include<stdio.h>

int main()
{
    int n,i,gcd;
    printf("Enter how many no.s u want to find gcd : ");
    scanf("%d",&n);
    int arr[n];
    printf("\nEnter your numbers below :- \n ");
    for(i=0;i<n;i++)
    {
        printf("\nEnter your %d number = ",i+1);
        scanf("%d",&arr[i]);
    }
    gcd=arr[0];
    int j=1;
    while(j<n)
    {
       if(arr[j]%gcd==0)
       {
           j++;
       }
       else
       {
           gcd=arr[j]%gcd;
           i++;
       }
    }
    printf("\nGCD of k no.s = %d ",gcd);
    return 0;
}

詳細については、これを参照してください website さらなる説明.......

0
Sam Smith

以下は、gcd(a、b、c)= gcd(a、gcd(b、c))というプロパティを使用するgcdメソッドです。
すでに最適化されているため、BigIntegerのgcdメソッドを使用します。

public static BigInteger gcd(BigInteger[] parts){
    BigInteger gcd = parts[0];
    for(int i = 1; i < parts.length; i++)
        gcd = parts[i].gcd(gcd);
    return gcd;
}
0
James McDowell

任意の桁数の再帰JavaScript(ES6)ワンライナー。

const gcd = (a, b, ...c) => b ? gcd(b, a % b, ...c) : c.length ? gcd(a, ...c) : Math.abs(a);
0
Lachlan Hunt