美文网首页
算法:辗转相除法

算法:辗转相除法

作者: Caolongs | 来源:发表于2017-12-14 10:06 被阅读80次

题目:要求方法传两个正整数参数,返回值就是他们的最大公约数。

解法一:(性能最差)

public static int getGreatestCommonDivisor(int numberA, intnumberB) {
    int smallNumber = numberA < numberB ? numberA : numberB;
    int bigNumber = numberA > numberB ? numberA : numberB;
    if(bigNumber % smallNumber == 0) {
      return smallNumber;
    }
    int greatestCommonDivisor = 1;
    for(int i = 2; i <= smallNumber/2; i ++){
      if(numberA%i==0 && numberB%i==0) {
        greatestCommonDivisor = i;
      }
    }
  return greatestCommonDivisor;
}

思路:暴力枚举的方法,试图寻找一个合适的整数i,
  看看这个整数能否被两个整型参数numberA和numberB同时整除。

解法二:
辗转相除法,又名欧几里得算法(Euclidean algorithm),目的是求出两个正整数的最大公约数。
定理:两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。

//方法入口
public static int getGreatestCommonDivisor(int numberA, int numberB) {
  int result = 1;
  if (numberA > numberB) {
    result = gcd(numberA,numberB);
  } else {
    result = gcd(numberB,numberA);
  }
  return result;
}
//递归计算最大公约数
private static int gcd(int a, int b) {
  if(a%b == 0) 
    return b;
  else
    return gcd(b, a%b);
}

缺点:当两个整型数较大时,做a%b取模运算能力会比较低


解法三:
更相减损术,出自于中古代的《九章算术》,也是一种求最大公约数的算法。
原理:两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小术的最大公约数。比如10和25,25减去10的差是15,那么10和25的最大公约数,等同于10和15的最大公约数。

public static int gcd(int numberA, int numberB) {
  if(nummberA == numberB)
    return numberB;
  if(numberA < numberB)
    return gcd(numberB - numberA, numberA)
  else
    return gcd(numberA - numberB, numberB);
}

缺点:更相损减数是不稳定的算法,当两数相差悬殊时,比如计算10000和1,要递归9999次


优化解法:
把辗转相除法和更相损减数的优势结合起来,在更相损减数的基础上使用移位运算。
众所周知,移位运算的性能非常快。对于给定的正整数a和b,不难得到如下结论。其中gcd(a,b)的意思是啊a,b的最大公约数:

当a和b均为偶数时,gcd(a,b) = 2*gcd(a/2, b/2) = 2*gcd(a>>1,b>>1)

当a为偶数,b为奇数,gcd(a,b) = gcd(a/2,b) = gcd(a>>1,b)

当a为奇数,b为偶数,gcd(a,b) = gcd(a,b/2) = gcd(a,b>>1)

当a和b均为奇数,利用更相损减数运算一次,gcd(a,b) = gcd(b,a-b),
此时a-b必然是偶数,又可以继续进行移位运算。
public static int gcd(int numberA, int numberB) {
  if(numberA == numberB)
    return numberA;
  if(numberA < numberB)
    //保证参数A永远大于等于参数B,为减少代码量
    return gcd(numberB,numberA)
  else {
    //和1做按位与运算,判断奇偶
    if(!numberA&1 && !numberB&1)
      return gcd(numberA>>1,numberB>>1) << 1;
    else if(!numberA&1 &&numberB&1)
      return gcd(numberA>>1, numberB);
    else if(numberA&1 && !number&1)
      return gcd(numberA, numberB>>1);
    else
      return gcd(numberA, numberA - numberB);
  }
}

1. 暴力枚举法:时间复杂度是O(min(a,b))
2. 辗转相除法:时间复杂度不太好计算,可以近似为O(long(max(a,b))),但是取模运算性能较差。
3. 更相减损法:避免了取模运算,但是算法性能不稳定,最坏时间复杂度为O(max(a,b))
4. 更相减损术与一位结合:不但避免了取模运算,而且算法稳定,时间复杂度为O(long(max(a,b)))

其他.....

相关文章

  • 算法-辗转相除法

    算法:辗转相除法(欧几里得算法) GCD递归定理 辗转相除法算法概述 辗转相除法伪代码 辗转相除法代码实现 对于两...

  • 算法:辗转相除法

    题目:要求方法传两个正整数参数,返回值就是他们的最大公约数。 解法一:(性能最差) 解法二:辗转相除法,又名欧几里...

  • 辗转相除法求最大公因数 2020-03-12

    今天做了一道题,需要求最大公因数,已经完全把辗转相除法忘记了,特此记录 辗转相除法 辗转相除法,也叫欧几里得算法,...

  • 扩展欧几里德算法

    扩展欧几里得算法(英语:Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)...

  • 扩展欧几里得算法

    扩展欧几里得算法(Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)的扩展...

  • 最大公约数

    . 欧几里德算法和扩展欧几里德算法 欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。...

  • 辗转相除法,最大公约数,最小公倍数

    辗转相除法, 又名欧几里德算法(Euclidean algorithm)乃求两个正整数之最大公约数的算法。 算法描...

  • 欧几里得算法(辗转相除法)

    介绍 欧几里得算法,又称辗转相除法,用于计算两个整数的最大公约数。 原理 下面通过一个例子介绍其原理:计算105和...

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

    在数学中,欧几里得算法,又称辗转相除法,是求最大公约数(greatest common divisor)的算法。辗...

  • C++ 辗转相除法 - 求最大公约数

    辗转相除法, 又名欧几里德算法(Euclidean algorithm)乃求两个正整数之最大公因子的算法。它是已知...

网友评论

      本文标题:算法:辗转相除法

      本文链接:https://www.haomeiwen.com/subject/cjeibxtx.html