算法怎么就这么难?----使用欧几里得算法求两数的最大公约数

本人菜鸟一枚,上午在看书的时候突然看到了求最大公约数的一个例题,突然就想到以前好像看过一个欧几里得算法,故又上网仔细找了一下欧几里得算法的原理。可能是本人时间长没看算法,脑子都生锈了。

看了几个讲解欧几里得算法的文章,大都只给公式,然后说了一大堆因为、、、、在我还没看懂的时候,突然来了个所以、、、然后公式就这样推出来的。⊙﹏⊙b汗!

经过我这令人捉急的小脑袋转了半天,最后有了点眉目,所以拿出来和大家分享一下!

1.首先说一下:欧几里得算法是求两个数的最大公约数的,你可能会问:什么是最大公约数?

(⊙﹏⊙我在一开始看到这个问题的时候,我就突然脑子短路,竟然不知道最大公约数是什么了)

最大公约数:即能够同时被两个数整除的那个最大的数。例如:8是16和8的公约数,因为16%8和8%8都等于零嘛!但4也是啊!所以两个数的公约数会有很多,但我们要找出那个最大的!

2.让我们来使用算式分析一下,假设求x和y的最大公约数。

a).先假设x>y,x和y的最大公约数用f(x,y)表示

b).假设   x/y = a;

x%y = b;

所以:a*y + b = x

(这个应该能看出来,因为a为x除以y的整数部分,b为x除以y的余数部分,所以a*y + b = x)

将上面那个式子调换一下位置得到:b = x – a*y;

因为x和y都能够被f(x,y)整除    -----因为f(x,y)是x和y的最大公约数嘛

所以 b 也能够被f(x,y)整除      -----即x和y的最大公约数f(x,y),它也是b的约数,所以求x和y的最大公约数也就相当于求y和b的最大公约数。(你可能会问,为什么本来求x和y的最大公约数,最后转了半天变成了求y的b的公约数了?因为 y < x嘛,而且x%y肯定也小于y,所以,这样一来,我们就把求最大公约数的范围缩小了啊)

所以、欧几里得的公式也就是这么来的f(x,y) = f(y,x%y);

所以这个算法的实现也就是不停的迭代,直到找出了x%y等于0时,则停止迭代,那个时候最大公约数也就是y了(因为x%y都等于0了,所以x和y的最大公约数也就是y本身了)。

3.上面可能说得有点啰嗦了,大家莫怪,本人也是想讲得更清楚嘛!下面直接附上代码实现部分:

public static int gcd(int x, int y){
        //防止输入为0,导致程序出错
        if(x == 0 || y == 0){return 0;}
        //添加一个判断保证x > y
        if(x < y){
            int temp = x;
            temp = y;
            y = x;
        }
        //算法实现
        if(x%y == 0){
            return y;
        }else
        {
            return gcd(y,x%y);
        }
    }

其实还有好多其它的优秀的算法,在这里就先不提了,毕竟欧几里得算法就挺高效的。在有些公司,这道题还作为笔试题出现过呢,所以,即将毕业去找工作的未来程序员,还是应该好好看一下的!O(∩_∩)O哈哈~

算法怎么就这么难?----使用欧几里得算法求两数的最大公约数

时间: 2024-10-24 07:58:42

算法怎么就这么难?----使用欧几里得算法求两数的最大公约数的相关文章

欧几里得算法求两个整数的最大公因数

unsigned int Gcd (unsigned int m,unsigned int n){ unsigned int rem; while(n>0){ rem = m % n; m = n; n = rem; } return m; } 对于m<n的情况,第一次循环m,n会交换 算法的时间复杂度计算 时间复杂度 logn 若M > N,则第一次循环交换M和N. 若想分析其时间复杂度,则要求循环次数,即生成余数的次数. 可以证明: 当M > N, 则M % N < M

欧几里得算法求最大公约数(gcd)

关于欧几里得算法求最大公约数算法, 代码如下: int gcd( int a , int b ) { if( b == 0 ) return a ; else gcd( b , a % b ) ; } 证明: 对于a,b,有a = kb + r  (a , k , b , r 均为整数),其中r = a mod b . 令d为a和b的一个公约数,则d|a,d|b(即a.b都被d整除), 那么 r =a - kb ,两边同时除以d 得 r/d = a/d - kb/d = m (m为整数,因为r也

欧几里得算法求最大公约数+最小公倍数

1,两个数互质:如果说两个数的公因数只有1,则可以说这两个数互质. 欧几里得算法求最大公约数: 首先求最大公约数,假设我们要求a和b的最大公约数 设a mod b = c: 可以得到一下的递推过程: a = kb + c ; 假设a , b 的最大公约数为d,则可以得到: a = md , b = nd; 可知m , n 互质: c = a - kb = md - knd = (m-kn)d; 我们已经知道m,n互质,则可以知道n和m-kn互质,则c和b的最大公约数也是d; 所以由以上的推论,我

欧几里得算法 - 计算两个正整数的最大公约数

欧几里得算法-计算两个正整数a,b的最大公约数 #定理:gcd(a,b) = gcd(b, a mod b) 终止条件:余数等于0 返回结果:余数等于0时的除数b # -*- coding: utf-8 -*- __author__ = 'nob' #迭代欧几里得 def iterative_gcd(a, b):     r = a % b     while(r):         a = b         b = r         r = a % b     return b     #

欧几里得算法——求取最小公约数

1 import java.util.Scanner; 2 3 /** 4 * Created by Administrator on 14-5-20. 5 */ 6 public class Euclid { 7 public static void main(String[] args){ 8 Scanner scanner=new Scanner(System.in); 9 String str=scanner.nextLine(); 10 int a=Integer.parseInt(s

对分查找、欧几里得算法求最大公约数

对分查找 1 int BinarySearch(const int A[], int x, int N) 2 { 3 int low, mid, high; 4 low = 0, high = N - 1; 5 while(low <= high) 6 { 7 mid = (low + high) / 2; 8 if(A[mid] < x) 9 low = mid + 1; 10 else 11 if(A[mid] > x) 12 high = mid - 1; 13 else 14 r

求两个数的最大公约数,辗转相除法与更相减损法(递归迭代)

问题:给出两个数a和b,求出他们的最大公约数(greatest common divisor). 解法一:辗转相除法,又叫欧几里得算法.两个正整数a和b(a>b),他们的最大公约数等于a除以b的余数和b之间的最大公约数. 比如10和25,25除以10余5,那么10和25的最大公约数等同于5和10之间的最大公约数. //辗转相除法 递归解法 int gcd(int a,int b){ if(a%b==0) return b; return (b,a%b); } //辗转相除法 迭代解法int gc

拓展欧几里得算法求不定方程

对于 ax+by=gcd(a,b) 这样的方程,可以用扩展欧几里得算法exgcd求出一组通解. 根据欧几里得求gcd: gcd(a,b)=gcd(b,a%b) 可得 bx+(a%b)y=gcd(b,a%b) 根据 a%b=a−(a/b)∗b 可得 bx+ay−(a/b)b∗y=gcd(b,a%b) 化简得 ay+b(x−(a/b)y)=gcd(b,a%b) x′=y,y′=(x−(a/b)y) ax′+by′=gcd(b,a%b)<=>ax+by=gcd(a,b) 根据 gcd(a,0)=a

关于欧几里得算法求最大公约数,即OJ1029的参考解法

1 #include <stdio.h> 2 int main(int argc, char *argv[]) 3 { 4 int a,b,c; 5 scanf("%d %d",&a,&b); 6 while(b>0) 7 { 8 c=a%b; 9 a=b; 10 b=c; 11 } 12 printf("%d\n",a); 13 return 0; 14 }