n个数的最大公约数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingangxin666/article/details/82729442

基本概念介绍

最大公因数

在数学分析的叙述中,如果nd都是整数而且存在某个整数c,使得n = cd,就说dn的一个因数,或说nd的一个倍数,记作d|n(读作d整除n)。如果d|ad|b我们就称dab的一个公因数。对每一对整数都有一个公因数d,形如d = ax+by,其中xy都是整数,并且ab的每一个公因数都能整除这个dd的绝对值叫做最大公因数,记为gcd(a,b)

最小公倍数

最小公倍数数论 中的一个概念。若有一个数X,可以被另外两个数A、B整除,且X大于(或等于)A和B,则X为A和B的公倍数。A和B的公倍数有无限个,而所有的公倍数中,最小的公倍数就叫做最小公倍数。

与最大公因数之关系
两个整数的最小公倍数与最大公因数之间有如下的关系:

\operatorname {lcm}(a,b)={\frac  { | a\cdot 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));
}

猜你喜欢

转载自blog.csdn.net/jingangxin666/article/details/82729442