あなたのFindMultiple()方法は悪くない、
static void FindMultiple()
{
long lcm=1;
for(long i=2;i<=20;i++)
{
lcm=FindLcm(lcm,i);
}
System.out.println("Lcm="+lcm);
}
かなり優れたアルゴリズムを実装しています。あなたの問題はFindLcm()、厄介なパフォーマンスのバグが含まれていることです。
static long FindLcm(long a,long b)
{
long lcm,hcf = 0;
long i=1;
// This sets ger to max(a,b) - why?
long ger=a>b?a:b;
// This would return a wrong result if a == b
// that never happens here, though
while(i<ger)
{
if((a%i==0) && (b%i==0))
hcf=i;
i++;
}
lcm=(a*b)/hcf;
return lcm;
}
2 つの引数のうち大きい方に到達するまでループします。累積的な LCM は急速に成長するため、かなりの時間がかかります。ただし、2 つの (正の) 数値の GCD (または必要に応じて HCF) は、2 つの小さい方よりも大きくすることはできません。したがって、2 つの引数のうち小さい方に到達するまでループすると、反復回数は最大で 20 回になり、( の場合i = 2, ..., 20) 19 回実行されます。計算量はわずかです。
に変更
long ger = a < b ? a : b;
while(i <= ger) {
私に与えます(印刷を測定するのではなく、タイミングコードを追加します):
17705 nanoseconds
Lcm=232792560
したがって、計算にかかる時間は 20マイクロ秒未満です。ユークリッド アルゴリズムを使用して最大公約数を見つければ、これを 6 マイクロ秒未満に簡単に押し下げることができます。
static long gcd(long a, long b) {
while(b > 0) {
a %= b;
if (a == 0) return b;
b %= a;
}
return a;
}
GCDを直接使用する場合は5未満
lcm *= i/gcd(lcm,i);
でFindMultiple()。