zoukankan      html  css  js  c++  java
  • 求两个数的最大公约数,辗转相除法与更相减损法(递归迭代)

    问题:给出两个数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
    gcd2(int a,int b){ int t; while(b!=0){ t=b; b=a%b; a=t; } return a; }

    解法二:更相减损术,出自中国古代的《九章算术》。两个正整数a和b(a>b),他们的最大公约数等于a-b的差值c和较小数b的最大公约数。

    比如10和25,25-10=15,那么10和25的最大公约数等于10和15的最大公约数。

    //更相减损术  递归 
    int gcd3(int a,int b){
        if(a==b)
            return a;
        if(a>b)
            return gcd(a-b,b);
        else
            return gcd(b-a,a); 
    }
    //更相减损术  迭代
    int gcd4(int a,int b){
        while(a*b!=0){
            if(a>b)
                a=a-b;
            else
                b=b-a;    
        }
        return a?a:b;
    }

    改进:更相减损术是不稳定的算法,当两个数相差悬殊时,如10000和1的最大公约数,要递归9999次。

    做法;

    当a和b都是偶数时,gcd(a,b)=2*gcd(a/2,b/2)=2*gcd(a>>1,b>>1)。

    当a是奇数,b是偶数时,gcd(a,b)=gcd(a,b/2)=gcd(a,b>>1)。

    当a是偶数,b是奇数时,gcd(a,b)=gcd(a/2,b)=gcd(a>>1,b)。

    当a和b都是奇数数时,gcd(a,b)=gcd(a-b,b)。

    //改进版:
    int gcd5(int a,int b){
        if(a==b)
            return a;
        else if(a<b)
            return gcd5(b,a);    //始终让 a>b
        else{
            if(!(a&1)&&!(b&1)){    //两数都为偶数 
                return gcd5(a>>1,b>>1)<<1;
            }else if((a&1)&&!(b&1)){    //a奇数 b偶数 
                return gcd5(a,b>>1);
            }else if(!(a&1)&&(b&1)){    //a偶数 b奇数 
                return gcd5(a>>1,b);
            }else
                return gcd(a,a-b);        //都是奇数 相减 
            
        } 
    }

    算法复杂度:

    辗转相除法:O(log(max(a,b)))

    更相减损法:O(max(a,b))

    改进更相减损法:O(log(max(a,b)))

  • 相关阅读:
    Python学习第42天(ftp习题实现day4)
    Python学习第41天(ftp习题实现day3)
    Python学习第40天(ftp习题实现day2)
    Python学习第39天(ftp习题实现day1)
    Python学习第38天(文件处理,os、sys、pickle模块复习)
    Python学习第37天(socketserver继承原理、通讯加密)
    Python学习第36天(socketserver模块导入)
    Python学习第35天(粘包)
    个人读书笔记04—业务用例图
    命令模式
  • 原文地址:https://www.cnblogs.com/hekuiFlye/p/9379276.html
Copyright © 2011-2022 走看看