n数の最大公約数を計算する最速の方法は何ですか?
LehmerのGCDアルゴリズム を使用する必要があります。
再帰なし:
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);
}
}
最初に数値をソートし、最小の2つの数値から再帰的にgcdを計算することができます。
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個の番号で試すことはできませんでした。
ユークリッドアルゴリズムを使用します。
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);
分割征服を使用できます。 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
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);
(いくつかの例で動作しますが、実際にはテストされていません)
//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;
}
以下は、配列を使用して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 さらなる説明.......
以下は、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;
}
任意の桁数の再帰JavaScript(ES6)ワンライナー。
const gcd = (a, b, ...c) => b ? gcd(b, a % b, ...c) : c.length ? gcd(a, ...c) : Math.abs(a);