求解最大公约数以及最小公倍数

  最大公约数和最小公倍数求解,常用的方法是短除法进行因式分解,然后最大公约数是所有公共因子的乘积,最小公倍数是所有因子的乘积。
本质上求最小公倍数就是求最大公倍数:x=m*ay=m*b;m是最大公约数,那最小公倍数就是m*a*b。所以可以得到最大公约数与最小公倍数的关系:

LCM(A,B) × GCD(A,B)=A × B
其中LCM是最小公倍数,GCD是最大公约数

来源:https://blog.csdn.net/Holmofy/article/details/76401074
作者总结出来的结论非常的有用,我们后续就根据这个思路去写算法。

辗转相除法(欧几里得算法)求最大公约数

辗转相除法:辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,除数去除出现的余数(第一余数),再用第一余数去除出现的余数(第二余数),如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
来源:https://baike.baidu.com/item/辗转相除法/4625352?fr=aladdin

注:百度百科里面的描述好像不对。大家可以比较下

具体算法如下:

int max_gcd(int a,int b){
    if (a <= 0 || b <= 0) {
        printf("please > 0\n");
        return -1;
    }
    if (a<b) {
        int tmp = a;
        a= b;
        b = tmp;
    }
    
    int r;
    while (a%b > 0) {
        r = a%b;
        a = b;
        b = r;
    }
    return b;
}

辗转相除法的时间复杂度:我们已知斐波纳契数列增长速度是指数,那么待分析的数列也是指数增长.设欧几里得算法需要k次,那么j=O(2^k),则k=O(lg j).

结合文章开头对于公约数的概念,我这边还有另外的一种方案去实现,具体代码如下:

int max_gcd1(int a,int b){
    if (a <= 0 || b <= 0) {
        printf("please > 0\n");
        return -1;
    }
    if (a<b) {
        int tmp = a;
        a= b;
        b = tmp;
    }
    int max = 1;
    for (int i = 1; i<=b; i++) {
        if (b%i == 0 && a%i == 0) {
            int tmpMax = max * i;
            if (tmpMax <= b) {
                if (b%tmpMax == 0 && a%tmpMax == 0){
                    max = tmpMax;
                    i = tmpMax;
                }else{
                    max = i;
                }
            }else{
                max = i;
            }
        
        }
    }
    return max;
}

大家可以清晰的感觉到无论是从运算的速度,以及逻辑的清晰度来说,辗转相除法都有非常大的优势。

  在网上搜了一下,发现我国古代数学家提出了一个更相减损法的算法去求最大公约数。描述如下:
 第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
  第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
  则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。
  根据描述,我这边实现如下:

int max_gcd2(int a,int b){
    int c = 1;
    while (a%2 == 0 && b%2 == 0) {
        c *= 2;
        a = a/2;
        b = b/2;
    }
    
    while (a != b) {
        if (a > b) {
            a = a - b;
        }else{
            b = b - a;
        }
    }
    return a * c;
    
}

两种算法的区别

(1)两者都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时计算次数的区别较明显。

(2)从结果体现形式来看,辗转相除法体现结果是以相除余数为0则得到,而更相减损术则以减数与差相等而得到。
转载地址:https://blog.csdn.net/Holmofy/article/details/76401074

更多优质文章,可以微信扫码关注:
这里写图片描述

发布了231 篇原创文章 · 获赞 110 · 访问量 60万+

猜你喜欢

转载自blog.csdn.net/HHL110120/article/details/97612019