【编程之美2.7】求最大公约数的最优算法

原创 2013年12月04日 22:30:32
public class euclid {

	public static void main(String[] args) {
			int m = 0, n = 0;
			int temp = 0;
			Scanner scanner = new Scanner(System.in);
			m = scanner.nextInt();
			n = scanner.nextInt();
			scanner.close();
			if (m < n)
			{
				temp = n;
				n = m;
				m = temp;
			}
			
			//euclid
			while (m % n != 0)
			{
				int r = m % n;
				m = n;
				n = r;
			}
			System.out.println(n);
	}

}

 算法的主要思想:令m = max, n = min;

 1. 如果 m % n == 0,那么n便是最大公约数;

 2. 如果1不成立, 那么令 r = m % n,m = n, n = r,重复1的操作;

 之前在求两个数的最大公约数一直用的比较笨拙的方法,既费时又费力。


2014-5-12 10:49 重新编辑:

上面算法的性能在小数据量的情况下效果不错,但是如果给两个很大的数,除法和求余操作是相当耗时的,代价会很大,所以算法需要进一步的优化:

对于两个数x和y,两个数的最大公约数有如下特点:

(1)如果y=k*y1, x=k*x1,那么有f(x, y)=k * f(x1, y1);

(2)如果x = p * x1, 假设p是素数, 且y % p != 0,那么f(x, y) = f(p * x1, y1) = f(x1, y1);

(3)如果k = f(x, y),那么k = f(x-y, y),反之也成立;

因为我们平时计算的时候移位操作的效率要远胜于乘除法,所以取素数p=2,结合上述的性质,我们便能得出以下结果的分类讨论:

1. 如果x和y都是偶数,那么依据性质(1),会有f(x, y) = 2 * f(x/2, y/2);

2. 如果x是偶数,y是奇数,那么依据性质(2),会有f(x, y) = f(2 * x1, y) = f(x >> 1, y);

3. 如果x是奇数,y是偶数,那么依据性质(2),会有f(x, y) = f(x, 2 * y1) = f(x, y >> 1);

4. 如果x和y都是奇数,那么依据性质(3),会有f(x, y) = f(max(x, y) - min(x,y), min(x,y));

因为奇数的差一定是偶数,所以下一步一定会是移位运算,可以避免大规模的相减运算。

按上面的四个步骤我们用移位运算取代了除法运算,避免了除法的大规模开销又避免了大规模的减法运算,性能较好。

【编程之美2.7】求最大公约数

int gcd(int x,int y) { if(x>1,y>>1)1,y);
  • panpan639944806
  • panpan639944806
  • 2012年11月11日 14:52
  • 277

求最大公约数的高效率算法

声明:下文中的算法与数学原理,都是从《编程之美》的2.7节中的解法三看到后,摘抄和修改而来的。 数学原理公式: 若x,y均为偶数,f(x,y) = 2 * f(x/2,y/2); 若...
  • u014653197
  • u014653197
  • 2016年09月19日 21:03
  • 1870

编程之美读书笔记(5)最大公约数

问题: 求两个数的最大公约数 解法一: 欧几里得辗转相除法: f(x,y) = GCD(x,y), 取k = x / y, b = x % y,则:x = k*y + b; 如果一个数能整除...
  • SJF0115
  • SJF0115
  • 2013年02月25日 13:01
  • 5389

【编程之美】2.7最大公约数问题

问题: 求两个数的最大公约数 解法一: 欧几里得辗转相除法: f(x,y) = GCD(x,y), 取k = x / y, b = x % y,则:x = k*y + b; ...
  • a45872055555
  • a45872055555
  • 2014年06月27日 00:01
  • 326

编程之美——2.7最大公约数

这里提供了一种高效的解决方法,值得借鉴。   需要注意的是程序GCD函数的第二行,当其中一个值为0的时候返回另外一个值,否则导致栈溢出(因为没有非递归的结束条件!)   代码如下:   /...
  • hitrose27
  • hitrose27
  • 2011年04月02日 13:22
  • 613

编程之美2.7——最大公约数问题

1、辗转相除法 int gcd1(int x, int y) { if(y == 0) return x; else return gcd1(y, x % y); } 2、辗转相减法 ...
  • wxl3105
  • wxl3105
  • 2012年06月14日 19:34
  • 511

编程之美 2.7最大公约数问题

编程之美 2.7最大公约数问题 bool isEven(int n) { return (n&1) == 0; } int gcd(int x, int y)//注意递归的基准情况和x,y同...
  • zjhhust
  • zjhhust
  • 2012年10月24日 15:32
  • 140

编程之美--2.7 最大公约数问题

解答 1 根据书上的理解,有三种方式:辗转相除法,辗转...
  • seawade
  • seawade
  • 2014年09月02日 07:34
  • 313

编程之美 2.7 最大公约数问题

2.7 最大公约数问题 问题描述: 求2个正正数的最大公约数,如果2个数很大,有什么简单的算法吗?  解法1:辗转相除法  假设f(x, y) 表示x,y的最大公约数是g,而k=x/y,b...
  • u012605629
  • u012605629
  • 2014年12月03日 17:02
  • 283

编程之美 -- 2.7 最大公约数问题

题目描述 求解X 和 Y 的最大公约数f(x, y) 解法一: 使用辗转相除法,f(x, y) = f(y, x % y), x 和 y 数字偏大则取模运算偏多而开销大 解法二:相...
  • java_wliang
  • java_wliang
  • 2015年04月10日 09:32
  • 313
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【编程之美2.7】求最大公约数的最优算法
举报原因:
原因补充:

(最多只允许输入30个字)