C语言求最大公约数及最小公倍数

C语言求最大公约数及最小公倍数

1. 最大公约数

1.1 定义

​ 最大公约数(Greatest Common Divisor,GCD),也称最大公因数、最大公因子,是一种数学概念,指两个或多个整数共有约数中最大的一个。

1.2 解法一:常规法(暴力法)

1.2.1 定义

由于最大公约数的本质是一个最大的能同时被两整数整除的自然数。所以我们先比较两数大小,从较大数开始向上递增,直到找到那个最小公倍数。

1.2.2 代码实现

int gcd4(int a, int b)
{ 
    //首先找到两个数中较大的数,用a存储较大数
    if (a < b)
    { 
        int temp = a;
        a = b;
        b = temp;
    }
    //从较大数开始寻找符合条件的最大公约数
    for (int i = a; i > 0; --i)
    { 
        if (a % i == 0 && b % i == 0)
        { 
            return i;
        }
    }
}

1.3 解法二:辗转相除法(欧几里德法)

1.3.1方法解释:

用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。

1.3.2实例:

例如,求(319,377):

∵ 319÷377=0(余319)

∴(319,377)=(377,319);

∵ 377÷319=1(余58)

∴(377,319)=(319,58);

∵ 319÷58=5(余29)

∴ (319,58)=(58,29);

∵ 58÷29=2(余0)

∴ (58,29)= 29;

∴ (319,377)=29。

1.3.3 代码实现

/** * 递归版辗转相除法 * @param a * @param b * @return */
int gcd1(int a, int b)
{ 
    if (a % b == 0)
    { 
        return b;
    }
    else
    { 
        return gcd1(b, a % b);
    }
}

/** * 非递归辗转相除法求解最大公约数 * @param a * @param b * @return */
int gcd2(int a, int b)
{ 
    while (b != 0)
    { 
        int temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

1.4 解法二:更相减损法

1.4.1 方法解释:

(如果需要对分数进行约分,那么)可以折半的话,就折半(也就是用2来约分)。如果不可以折半的话,那么就比较分母和分子的大小,用大数减去小数,互相减来减去,一直到减数与差相等为止,用这个相等的数字来约分,这个数就是最大公约数;

1.4.2 步骤:

  • 第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。

  • 第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。

  • 则第一步中约掉的若干个2的积与第二步中等数的乘积就是所求的最大公约数。

1.4.3 实例:

  1. 用更相减损术求98与63的最大公约数。

解:由于63不是偶数,把98和63以大数减小数,并辗转相减:

98-63=35

63-35=28

35-28=7

28-7=21

21-7=14

14-7=7

所以,98和63的最大公约数等于7。

  1. 用更相减损术求260和104的最大公约数。

解:由于260和104均为偶数,首先用2约简得到130和52,再用2约简得到65和26。

此时65是奇数而26不是奇数,故把65和26辗转相减:

65-26=39

39-26=13

26-13=13

所以,260与104的最大公约数等于13乘以第一步中约掉的两个2,即1322=52。

1.4.4 代码实现

//定义静态变量,保存约掉的若干个2次数
static int count = 0;

int gcd3(int a, int b)
{ 
    int temp;
    //任意给定两个正整数;判断它们是否都是偶数。
    if (a % 2 == 0 && b % 2 == 0 && !count)
    { 
        //若是,则用2约简;若不是则执行第二步。
        a /= 2;
        b /= 2;
        //保存约掉的若干个2次数
        count += 2;
    }
    //以较大的数减较小的数,a中保存大数
    if (a < b)
    { 
        temp = a;
        a = b;
        b = temp;
    }
    //接着把所得的差与较小的数比较,并以大数减小数
    if (a - b != 0)
    { 
        //递归求解
        return gcd3(b, a - b);
    }
    else
    { 
        //计算完毕完后count要置为0,防止第二次调用时出错;
        //所以需要提前定义常量保存输出结果:约掉的若干个2的积与第二步中等数的乘积就是所求的最大公约数。
        int result = count * b;
        //置0
        count = 0;
        return result;
    }
}

2. 最小公倍数

2.1 定义

最小公倍数(Least Common Multiple(LCM))是一种数学概念,几个数共有的倍数叫做这几个数的公倍数,其中除0以外最小的一个公倍数,叫做这几个数的最小公倍数。

2.2 解法一:常规法(暴力法)

2.2.1 方法解释

由于最小公倍数的本质是一个最小的能同时被两整数整除的自然数。所以我们先比较两数大小,从较大数开始向上递增,直到找到那个最小公倍数。

2.2.2 代码实现

/** * 常规法求最小公倍数(暴力法) * @param a * @param b * @return */
int lcm1(int a, int b)
{ 
    //首先找到两个数中较大的数,用a存储较大数
    if (a < b)
    { 
        int temp = a;
        a = b;
        b = temp;
    }
    //从较大数开始寻找符合条件的最小公倍数
    for (int i = a;; ++i)
    { 
        if (i % a == 0 && i % b == 0)
        { 
            return i;
        }
    }
}

2.3 解法二:公式法

2.3.1 定义

由于两个数的乘积等于这两个数的最大公约数与最小公倍数的积。即(a,b)×[a,b]=a×b。所以,求两个数的最小公倍数,就可以先求出它们的最大公约数,然后用上述公式求出它们的最小公倍数。

2.3.2 实例

求[18,20],即得[18,20]=18×20÷(18,20)=18×20÷2=180。求几个自然数的最小公倍数,可以先求出其中两个数的最小公倍数,再求这个最小公倍数与第三个数的最小公倍数,依次求下去,直到最后一个为止。最后所得的那个最小公倍数,就是所求的几个数的最小公倍数。

2.3.3 代码实现

int lcm2(int a, int b)
{ 
    //lcd函数上面已经介绍
    return a*b/lcd(a,b);
}

约数,然后用上述公式求出它们的最小公倍数。

2.3.2 实例

求[18,20],即得[18,20]=18×20÷(18,20)=18×20÷2=180。求几个自然数的最小公倍数,可以先求出其中两个数的最小公倍数,再求这个最小公倍数与第三个数的最小公倍数,依次求下去,直到最后一个为止。最后所得的那个最小公倍数,就是所求的几个数的最小公倍数。

2.3.3 代码实现

int lcm2(int a, int b)
{ 
    //lcd函数上面已经介绍
    return a*b/lcd(a,b);
}
    原文作者:小白猿同学
    原文地址: https://blog.csdn.net/weixin_44421299/article/details/117136384
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞