版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingangxin666/article/details/82729442
基本概念介绍
最大公因数
在数学分析的叙述中,如果n和d都是整数而且存在某个整数c,使得n = cd,就说d是n的一个因数,或说n是d的一个倍数,记作d|n(读作d整除n)。如果d|a且d|b我们就称d是a和b的一个公因数。对每一对整数都有一个公因数d,形如d = ax+by,其中x和y都是整数,并且a和b的每一个公因数都能整除这个d。d的绝对值叫做最大公因数,记为gcd(a,b)
最小公倍数
最小公倍数是数论 中的一个概念。若有一个数X,可以被另外两个数A、B整除,且X大于(或等于)A和B,则X为A和B的公倍数。A和B的公倍数有无限个,而所有的公倍数中,最小的公倍数就叫做最小公倍数。
与最大公因数之关系
两个整数的最小公倍数与最大公因数之间有如下的关系:
辗转相除法
基于如下原理:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数
三个数的最大公约数的定义和两个数的相同,即是它们共有的素因数的积,它们或者也可以按下式计算:
GCD(a, b, c) = GCD(a, GCD(b, c)) = GCD(GCD(a, b), c) = GCD(GCD(a, c), b).
所以,欧几里得的辗转相除法实际可以计算任意多整数的最大公约数。
代码实现
两个数的最大公因数
c++普通版本
int gcd(int a, int b)
{
if (a < b) std::swap(a, b);
int temp;
while (temp)
{
temp = a % b;
a = b;
b = temp;
}
return a;
}
c++递归版本
int gcd(int a, int b)
{
if (a < b) std::swap(a, b);
if (b == 0) return a;
return gcd(b, a % b);
}
两个数的最小公倍数
c++版本
//gcd为最大公约数
int lcm(int a, int b)
{
return a * b / gcd(a, b);
}
n个数的最大公因数
//n个数的最大公约数算法
//计算范围是[0, n - 1]
int ngcd(std::vector<int> &a, int n)
{
if (n == 1) return a[0];
return gcd(a[n - 1], ngcd(a, n - 1));
}
//n个数的最大公约数算法
//计算范围是[left, right]
int ngcd(std::vector<int> &a, int left, int right)
{
if (left == right) return a[left];
return gcd(a[right], ngcd(a,left, right-1));
}
n个数的最小公倍数
//n个数的最小公倍数算法
//计算范围是[0, n - 1]
int nlcm(std::vector<int> &a, int n)
{
if (n == 1) return a[0];
return lcm(a[n - 1], nlcm(a, n - 1));
}
//n个数的最小公倍数算法
//计算范围是[left, right]
int nlcm(std::vector<int> &a, int left, int right)
{
if (left == right) return a[left];
return lcm(a[right], nlcm(a, left, right - 1));
}