IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    欧几里德算法

    安·记发表于 2012-10-28 15:49:58
    love 0

    今天在群里看到有朋友提出一道面试题,是如何求得2个数的最大公约数。在《Javascrit权威指南》一书曾今中有提到相关的例子,其原理是使用欧几里得算法求得。

    在数学中,欧几里得算法,又称辗转相除法,是求两个正整数的最大公约数的算法。辗转相除法首次出现于欧几里得的《几何原本》中,而在中国则可以追溯至东汉出现的《九章算术》。其定理为:

    gcd(a,b) = gcd(b,a%b)

    即设两数为a、b,其中a>b,a%b为a除以b以后的余数且a%b不为0,用gcd(a,b)表示a和b的最大公约数。也就是说,两个数的最大公约数=(较小的数)和(较大的数除以较小的数的余数)的最大公约数。

    基于上述等式,我们先来求 a=481 和 b=221 的最大公约数,解剖欧几里德算法计算过程:

    假设f为a和b的最大公约数
    a除以b的余数 等于 481%221 等于 39
    
    根据公式,那么f也等于221和39的公约数,我们继续求模
    221除以39的余数 等于 221%39 等于 26
    
    根据公式,f也等于39和26的公约数 ,我们继续求模
    39除以26的余数数 等于 39%26 等于 13
    
    根据公式,f 也等于26和13公约数,我们继续求模
    26除以13的余数数 等于 39%26 等于 0
    
    到这一步,26可以13被整除,说明他们的最大公约数也就是13,即f=13。
    

    通过这个等式,我们可以一步一步地缩小与原始数公约数相同的的一对数字,最后直到找到较大数能被较小数整除为止,那么较小数就是他们的最大公约数。

    在javascript中我们可以通过一个while循环来实现这个计算过程:

    function gcd(a, b){
            var t; //临时变量,用于储存值
            if(a<b){ //交换,确保a>=b
                t = b;
                b = a;
                a = t;
            }
            while(b!=0){
                t = b;
                b = a%b;
                a = t;
            }
            return a;
        }
        gcd(481, 221); //13

    或者我们可以通过一个递归来实现类似的计算:

    function gcd2(a, b){
            var t;
            if(a<b){
                t = b;
                b = a;
                a = t;
            }
            if(b != 0){
                return arguments.callee(b,a%b);
            }
            return a
        }
        gcd2(481, 221); //13


沪ICP备19023445号-2号
友情链接