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

求两个很大的数的最大公约数问题。

解法一:辗转相除法,但当数很大时,取模运算很耗时间。

解法二:利用f(x,y) = f(x-y, y)可以避免取模,但是当第一个数很大,而第二个数很小如1时,也比较耗时。

解法三:对于y和x来说,如果y=k*y1, x= k*x1,那么f(y,x)=k*f(y1,x1)。如果x=p*x1,假设p是素数,并且y%p!=0,那么f(x,y)=f(p*x1,y)=f(x1,y)。于是对于二进制表示的大整数而言可以每次除二了。

 1 BigInt gcd(BigInt x, bigInt y)
 2 {
 3      if(x<y)
 4             return gcd(y,x);
 5     if(y==0)
 6             return x;
 7     else
 8     {
 9          if(IsEven(x))
10         {
11             if(IsEven(y))
12                 return (gcd(x>>1,y>>1)<<1);
13             else
14                 return gcd(x>>1,y);
15         }
16         else
17         {
18             if(IsEven(y))
19                 return gcd(x,y>>1);
20             else
21                 return gcd(y,x-y);
22         }
23     }
24 }

时间: 2024-10-10 02:26:48

编程之美----最大公约数问题的相关文章

2.7 编程之美--最大公约数的3种解法[efficient method to solve gcd problem]

[本文链接] http://www.cnblogs.com/hellogiser/p/efficient-method-to-solve-gcd-problem.html [题目] 求两个正整数的最大公约数Greatest Common Divisor (GCD).如果两个正整数都很大,有什么简单的算法吗?例如,给定两个数1 100 100 210 001, 120 200 021,求出其最大公约数. [解法] [1. 辗转相除法] 辗转相除法:f(x,y) = f(y , x % y)(x>y

编程之美---最大公约数

该文出自于编程之美中关于最大公约数问题一章. 任意给定两个数字,得到其最大公约数 GCD(greatest common divisor),如果两个数字都很大怎么解决. 分析:最大公约数早在公元前300年,欧几里得的<几何原本>里就提出了一个高效率算法---辗转相除法. 解法一: 假设f(x,y)表示x,y的最大公约数,取k=x/y,b=x%y,则x=ky+b,如果一个数字能同时整除x,y,那么必能够同时整除b,y:而能够同时整除b,y的数必能够同时整除x,y,即x,y的公约数与b,y的公约数

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

问题: 求两个数的最大公约数 解法一: 欧几里得辗转相除法: f(x,y) = GCD(x,y), 取k = x / y, b = x % y,则:x = k*y + b; 如果一个数能整除x,y,则它也能整除b,y: 而且能整除b,y的数必能整除x,y,即x,y和b,y的公约数是相同的,其最大公约数也是相同的,即f(x,y) = f(y ,x % y) (x>=y>0) 例如,计算a = 1071和b = 462的最大公约数的过程如下:从1071中不断减去462直到小于462(可以减2次,即

编程之美-分层遍历二叉树

问题:给定一个二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号.那么分层遍历如图的二叉树,正确的输出应该为: <span style="font-size:14px;">1 2 3 4 5 6 7 8</span> 书中还给出了问题2:打印二叉树中的某层次的节点(从左到右),其中根结点为第0层,成功返回true,失败返回false 分析与解法 关于二叉树的问题,由于其本身固有的

读书问题之《编程之美》 -----12061161 赵梓皓

我阅读的书是<编程之美> 刚开始的时候阅读序,就觉得控制cpu利用率这个问题很好玩,所以重点看了这部分和解决办法,问题也都大部分是这部分的.那么问题就来了(挖掘机技术xxx?中国山东找蓝翔) 咳咳,问题在下面: 1.关于问题的提出.(也是一点点建议) 本书的主要内容是告诉读者如何思考问题和解决问题.但是提出问题也是很重要的,正如爱因斯坦所说“提出一个问题往往比解决一个问题更重要”,很多面试题(比如井盖为啥是圆的)我觉得正常人很少会想到.所以,这个问题是怎么想出来的...我很好奇.也希望作者能够

《编程之美》3.6判断链表是否相交之扩展:链表找环方法证明

先看看原题:<编程之美>3.6编程判断两个链表是否相交,原题假设两个链表不带环. 为了防止剧透使得没看过原题目的读者丧失思考的乐趣,我把最好的解法隐藏起来.由于这个问题本身的解答并不是本文的重点,扩展问题也采用这种形式呈现. 注:位于(*)符号之间的文字出自于:http://blog.csdn.net/v_july_v/article/details/6447013,作者v_JULY_v. 用指针p1.p2分别指向两个链表头,不断后移:最后到达各自表尾时,若p1==p2,那么两个链表必相交 用

编程之美之买票找零

题目:假设有2N个人在排队买票,其中有N个人手持50元的钞票,另外有N个人手持100元的钞票,假设开始售票时,售票处没有零钱,问这2N个人有多少种排队方式,不至使售票处出现找不开钱的局面? 分析:队伍的序号标为0,1,...,2n-1,并把50元看作左括号,100元看作右括号,合法序列即括号能完成配对的序列.对于一个合法的序列,第0个一定是左括号,它必然与某个右括号配对,记其位置为k.那么从1到k-1.k+1到2n-1也分别是两个合法序列.那么,k必然是奇数(1到k-1一共有偶数个),设k=2i

【编程之美】java实现重建二叉树

package com.cn.binarytree.utils; /** * @author 刘利娟 [email protected] * @version 创建时间:2014年7月20日 下午2:03:30 类说明: */ class Node { Node left; Node right; char chValue; Node(char chValue) { left = null; right = null; this.chValue = chValue; } } public cla

编程之美之字符串移位包含问题

[题目] 给定两个字符串s1和s2,要求判断s2是否能够被通过s1做循环移位(rotate)得到的字符串包含.例如,S1=AABCD和s2=CDAA,返回true:给定s1=ABCD和s2=ACBD,返回false. [分析] [思路一] 从题目中可以看出,我们可以使用最直接的方法对S1进行循环移动,再进行字符串包含的判断,从而遍历其所有的可能性. 字符串循环移动,时间复杂度为O(n),字符串包含判断,采用普通的方法,时间复杂度为O(n*m),总体复杂度为O(n*n*m). 字符串包含判断,若采