zoukankan      html  css  js  c++  java
  • 不同的GCD算法


    分类: C语言程序 28人阅读 评论(0) 收藏 举报

    早在公元前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的公约数是相同的,其最大公约数也是相同的,则有f(x, y)= f(y, x % y)(y > 0),如此便可把原问题转化为求两个更小数的最大公约数,直到其中一个数为0,剩下的另外一个数就是两者最大的公约数。

    证明如下:
    我们只需证明gcd(a,b)gcd(b,a%b)可以互相整除即可。
    对于gcd(a,b),它是a和b的线性组合中的最小正元素,gcd(b,a%b) 是b与a%b的一个线性组合,而a%b是a与b的一个线性组合,因而gcd(b,a%b)是一个a与b的线性组合,因为a,b都能被gcd(a,b)整除,因而任何一个a与b的线性组合都能被gcd(a,b)整除,所以gcd(b,a%b)能被gcd(a,b)整除。反之亦然。
    (摘自百度百科)
    这都是网上比较正式比较权威的解释,直接就拿来用了。
    下面是我写的一段代码,还有注释中是三种摘自网络上别人的不同解法。人家的代码简直精简到一塌糊涂。~~~~(>_<)~~~~ 
    #include<stdio.h>   /*欧几里得算法(辗转相除法)求最大公约数。*/
    int gcd(int m,int n);
    
    int main (void){
    	int m,n;
    	printf("请输入m和n的数值(都为正整数),将为你求出两个数的最大公约数:
    ");
    	scanf("%d %d",&m,&n);
    	printf("%d
    ",gcd(m,n));
    	return 0;
    }
    
    
    int gcd(int m,int n){                               //我的递归法
    	if(n==0)
    		return m;
    	return gcd(n,m%n);
    }
    

    int gcd(int a,int b)           //精简版递归法
    {  
        return (b>0)?gcd(b,a%b):a;  
    }  
    
    
    /*int gcd(int a,int b)           //位运算法。这个代码害怕不害怕。。
    {  
        while(b^=a^=b^=a%=b);  
        return a;  
    }  */

    话说看到位运算法的时候真被吓到了。。确实非常精炼!
    下面把这句提取出来,小小的分析一下。
    while(b^=a^=b^=a%=b);  

    因为两个数字进行三次异或运算可以交换数值。

    所以其实可以写为:
    while(b>0){
    a=a%b;         -->求出余数赋给a;
    b=b^a;          -->通过亦或运算,b的值变为其他值
    a=a^b;          -->a的值变为原b的值
    b=b^a;          -->b的值变为原a的值 
    }
    return  a;
    这样,当b为0的时候,a就是最大公约数,然后返回这个值即可:

    还有一种方法叫二进制gcd法                                                         


  • 相关阅读:
    UDK Stat命令
    绝地求生-全军出击手游
    UE3中的时间
    Git原理与命令大全
    【SpringCloud】Spring Cloud Alibaba 之 Nacos注册中心(二十七)
    【SpringCloud】Spring Cloud Alibaba 及 Nacos介绍(二十六)
    【Web】Keepalived+Nginx 实现高可用集群
    【SpringCloud】Spring Cloud Sleuth + Zipkin + RabbitMQ 集成(二十五)
    【SpringCloud】Spring Cloud Sleuth 日志跟踪(二十六)
    Spring框架学习笔记(5)——Spring Boot创建与使用
  • 原文地址:https://www.cnblogs.com/u013533289/p/4477277.html
Copyright © 2011-2022 走看看