质因数分解法、短除法、辗转相除法、更相减损法求最大公约数

通常我们在面试中都会遇到一道面试题,求两个数的最大公约数。这个我就深入理解,并解析一下这个题目。

首先,我们得理解,什么是最大公约数?以下是网上给出的答案:

最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。a,b的最大公约数记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有同样的记号。

简单来说,也就是能够同时被两个数整初的数中,最大的那一个。在数学中,我们求最大公约数有多种方法,常见的有质因数分解法、短除法、辗转相除法、更相减损法。

质因数分解法

  1. 质因数分解法:把一个合数分解成若干个质因数的乘积的形式

例如:求24和60的最大公约数,先分解质因数,得24=2×2×2×3,60=2×2×3×5,24与60的全部公有的质因数是2、2、3,它们的积是2×2×3=12,所以,(24,60)=12。

var ary_factor=[2,3,5,7];
var x_factor=[]
var greatest_common_divisor=get_factor(24,60);
alert(greatest_common_divisor)

function get_factor(a,b) {
    var a_factor=[];
    var b_factor=[];
    factor(a);
    a_factor=x_factor.sort();
    x_factor=[];
    factor(b);
    b_factor=x_factor.sort();
    return common_factor(a_factor,b_factor)

}
function common_factor(a_ary,b_ary) {
    var common_ary=[];
    var greatest_common_divisor=1;
    for(var j=0;jif(b_ary.indexOf(a_ary[j])!=-1) {
        common_ary.push(a_ary[j])
          b_ary.splice(b_ary.indexOf(a_ary[j]),1)
      }
    }
    if(common_ary.length!=0){
        for(var k=0;kreturn greatest_common_divisor;
}

function factor(x) {
    if (x==1){
        x_factor.push(x)
        return x_factor;
    };
    if(ary_factor.indexOf(x)!=-1){
        x_factor.push(x)
        return x_factor;
    }else{
        for(var i=0;iif(x%ary_factor[i]==0){
                x_factor.push(ary_factor[i]);
                x=x/ary_factor[i];
            }
        }
        factor(x);
    }
}

  短除法

  2.短除法:短除符号就是除号倒过来。短除就是在除法中写除数的地方写两个数共有的质因数,然后落下两个数被公有质因数整除的商,之后再除,以此类推,直到结果互质为止(两个数互质)。

  

var ary_factor=[2,3,5,7];
var common_factor=[]
var greatest_common_divisor=1;
alert( get_factor(12,18))
function get_factor(a,b) {
    if(a>b){
     var c=a;a=b;b=c;
    }
    if(a==1||b==1)return 1;
    if(a==b)return a;
    if(b%a==0)return a;
    var is_factor=ary_factor.indexOf(a)!=-1&&ary_factor.indexOf(b)!=-1;
    var is_one_factor=ary_factor.indexOf(a)!=-1&&b%a!=0;
    if(is_factor||is_one_factor){
        if(common_factor.length!=0){
            for(var k=0;kfor(var i=0;iif(a%ary_factor[i]==0&&b%ary_factor[i]==0&&ary_factor.indexOf(a)==-1&&ary_factor.indexOf(b)==-1){
            common_factor.push(ary_factor[i]);
            a=a/ary_factor[i];
            b=b/ary_factor[i];
            i=ary_factor.length+1;
            get_factor(a,b);
            break;
        }

    }
    return greatest_common_divisor;

}

  辗转相除

  3.辗转相除法:设两数为a、b(a>b),求a和b最大公约数(a,b)的步骤如下:用a除以b,得a÷b=q......r1(0≤r1)。若r1=0,则(a,b)=b;若r1≠0,则再用b除以r1,得b÷r1=q......r2 (0≤r2).若r2=0,则(a,b)=r1,若r2≠0,则继续用r1除以r2,……如此下去,直到能整除为止。其最后一个为被除数的余数的除数即为(a, b)。

例如:a=25,b=15,a/b=1......10,b/10=1......5,10/5=2.......0,最后一个为被除数余数的除数就是5,5就是所求最大公约数。

var greatest_common_divisor=1;
get_greatest_common_divisor(10,48);
alert(greatest_common_divisor)
function get_greatest_common_divisor(a,b) {
    var remainder=0;
    if(a>b){
        var c=a;a=b;b=c;
    }
    if(b%a==0){
        greatest_common_divisor=a;
        return;
    }else{
        remainder=b%a;
        get_greatest_common_divisor(remainder,a);
    }
    ;

}

 更相减损法

 4.更相减损法:一种在数学与计算机中可以应用的算法

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

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

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

var greatest_common_divisor=1;
get_greatest_common_divisor(48,30);
alert(greatest_common_divisor)
function get_greatest_common_divisor(a,b) {
    if(a>b){
        var c=a;a=b;b=c;
    }
   if(a%2==0&&b%2==0){
       a=a/2;b=b/2;
       greatest_common_divisor=greatest_common_divisor*2;
       get_greatest_common_divisor(a,b)
   }else{
       b=b-a;
       if((b-a)==0){
           greatest_common_divisor=greatest_common_divisor*a;
       }else {
           get_greatest_common_divisor(a,b)
       }
   }
}

历时n久,今天终于有时间把这篇文章补充完整。以上就是四种方式对最大公约数求解的方法以及程序,大家应该对哪种方式最优也有了自己的看法。当然我写的程序并不一定是最优的,有不完美的地方还请指出。

你可能感兴趣的:(javascript,算法,质因数分解法,最大公约数,短除法,辗转相除法,更相减损法)