计算两个整数的最小公倍数的最有效方法是什么?
我只是想出了这一点,但是肯定有一些不足之处。
int n=7, m=4, n1=n, m1=m;
while( m1 != n1 ){
if( m1 > n1 )
n1 += n;
else
m1 += m;
}
System.out.println( "lcm is " + m1 );
Answers:
的最小公倍数(LCM)a
和b
是他们的产品可以通过最大公约数(GCD)划分(即lcm(a, b) = ab/gcd(a,b)
)。
因此,问题就变成了如何找到gcd?该欧几里德算法是最大公因数一般是如何计算的。经典算法的直接实现是有效的,但是有些变化可以利用二进制算法来做得更好。参见Knuth的“计算机程序设计艺术”第2卷,“ Seminumicalical Algorithms”(第4.5.2节)。
long
或在其他情况下使用BigInteger
。两个int
值的LCM可以是long
。
int
。我们知道一个事实,即对某些价值观m
和n
它不能。我的观点是,如果你担心在计算溢出,你应该也担心最后的结果溢出。
long
可以表示最大为2 ^ 63-1 = 9223372036854775807807的整数),但是原始方法仍然会溢出(中间值为6 * p * p)。一个简单的重新排序可以大大提高算法的适用性,不管其类型如何(short
,int
,或long
)。
请记住,最小公倍数是最小整数,是两个或多个数字中每个数字的倍数。
如果您要找出三个整数的LCM,请按照下列步骤操作:
**Find the LCM of 19, 21, and 42.**
为每个数字写素数分解。19是质数。您无需考虑因素19。
21 = 3 × 7
42 = 2 × 3 × 7
19
重复每个素数因子出现在以上任何素数因子分解中的最大次数。
2×3×7×19 = 798
21、42和19的最小公倍数是798。
我认为“减少最大的公共分隔线”的方法应该更快。首先计算GCD(例如,使用Euclid算法),然后将两个数字的乘积除以GCD。
下面的C ++最佳解决方案
#include <iostream>
using namespace std;
long long gcd(long long int a, long long int b){
if(b==0)
return a;
return gcd(b,a%b);
}
long long lcm(long long a,long long b){
if(a>b)
return (a/gcd(a,b))*b;
else
return (b/gcd(a,b))*a;
}
int main()
{
long long int a ,b ;
cin>>a>>b;
cout<<lcm(a,b)<<endl;
return 0;
}
我不知道它是否经过优化,但可能是最简单的一种:
public void lcm(int a, int b)
{
if (a > b)
{
min = b;
max = a;
}
else
{
min = a;
max = b;
}
for (i = 1; i < max; i++)
{
if ((min*i)%max == 0)
{
res = min*i;
break;
}
}
Console.Write("{0}", res);
}
首先,您必须找到最大的公约数
for(int i=1; i<=a && i<=b; i++) {
if (i % a == 0 && i % b == 0)
{
gcd = i;
}
}
之后,使用GCD,您可以轻松找到这样的最小公倍数
lcm = a / gcd * b;
for (int i = a; i >= 0; i--)
,如果if语句返回true,则可以跳出循环。
取两个数中较大者的连续倍数,直到结果是较小数的倍数。
这可能工作。
public int LCM(int x, int y)
{
int larger = x>y? x: y,
smaller = x>y? y: x,
candidate = larger ;
while (candidate % smaller != 0) candidate += larger ;
return candidate;
}
C ++模板。编译时间
#include <iostream>
const int lhs = 8, rhs = 12;
template<int n, int mod_lhs=n % lhs, int mod_rhs=n % rhs> struct calc {
calc() { }
};
template<int n> struct calc<n, 0, 0> {
calc() { std::cout << n << std::endl; }
};
template<int n, int mod_rhs> struct calc<n, 0, mod_rhs> {
calc() { }
};
template<int n, int mod_lhs> struct calc <n, mod_lhs, 0> {
calc() { }
};
template<int n> struct lcm {
lcm() {
lcm<n-1>();
calc<n>();
}
};
template<> struct lcm<0> {
lcm() {}
};
int main() {
lcm<lhs * rhs>();
}
欧几里得GCD代码段
int findGCD(int a, int b) {
if(a < 0 || b < 0)
return -1;
if (a == 0)
return b;
else if (b == 0)
return a;
else
return findGCD(b, a % b);
}
使用欧几里得算法找到gcd,然后计算lcm除以gcd和b的乘积,这对我有用。
int euclidgcd(int a, int b){
if(b==0)
return a;
int a_rem = a % b;
return euclidgcd(b, a_rem);
}
long long lcm(int a, int b) {
int gcd=euclidgcd(a, b);
return (a/gcd*b);
}
int main() {
int a, b;
std::cin >> a >> b;
std::cout << lcm(a, b) << std::endl;
return 0;
}
在最有效的方法来计算LCM - 时间复杂度- O(日志(分(A,B)))
基本公式-LCM(a,b)=(a * b)/ GCD(a,b)
GCD(a,b)的时间复杂度是O(log(min(a(b,b)))
在这里您可以找到C,C ++,C#,Python等代码。单击此处
谢谢 !
lcm = a / gcd * b
而不是lcm = a * b / gcd
。