zoukankan      html  css  js  c++  java
  • Stein算法 求最大公约数

    欧几里德算法(辗转相除法)是计算两个数最大公约数的传统算法,它无论从理论还是从效率上都是很好的。但是他有一个致命的缺陷,这个缺陷只有在大素数时才会显现出来。

    Stein算法由 J. Stein 1961年提出,和欧几里德算法算法不同的是,Stein算法只有整数的移位和加减法

    为了说明Stein算法的正确性,首先必须注意到以下结论:

    gcd(a,a) = a,也就是一个数和他自身的公约数是其自身
    gcd(ka,kb) = k gcd(a,b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个偶数的最大公约数必然能被2整除。

    有了上述规律就可以给出Stein算法如下:

    1.如果A=0,B是最大公约数,算法结束
    2.如果B=0,A是最大公约数,算法结束
    3.设置A1 = A、B1=B和C1 = 1
    4.如果An和Bn都是偶数,则An+1 =An /2,Bn+1 =Bn /2,Cn+1 =Cn *2(注意,乘2只要把整数左移一位即可,除2只要把整数右移一位即可)
    5.如果An是偶数,Bn不是偶数,则An+1 =An /2,Bn+1 =Bn ,Cn+1 =Cn (很显然啦,2不是奇数的约数)
    6.如果Bn是偶数,An不是偶数,则Bn+1 =Bn /2,An+1 =An ,Cn+1 =Cn (很显然啦,2不是奇数的约数)
    7.如果An和Bn都不是偶数,则An+1 =|An -Bn|,Bn+1 =min(An,Bn),Cn+1 =Cn
    8.n++,转4

    C++实现:

    unsigned int gcd(unsigned int a,unsigned int b)
    {
    if(a<b) swap(a,b);
    if(b==0) return a;
    if(a%2==0&&b%2==0) return 2*gcd(a/2,b/2);
    if(a%2==0) return gcd(a/2,b);
    if(b%2==0) return gcd(a,b/2);
    return gcd((a+b)/2,(a-b)/2);
    }

    ANSI C:

    来自http://blog.csdn.net/ztj111/archive/2007/11/27/1905015.aspx

    unsigned int stein( unsigned int x, unsigned int y )
    /* return the greatest common divisor of x and y */
    {
    unsigned
    int factor = 0;
    unsigned
    int temp;
    if ( x < y ){
    temp
    = x;
    x
    = y;
    y
    = temp;
    }
    if ( 0 == y ) return 0;
    while ( x != y )
    {
    if ( x & 0x1 )
    {
    /* when x is odd */
    if ( y & 0x1 )
    {
    /* when x and y are both odd */
    y
    = ( x - y ) >> 1;
    x
    -= y;
    }
    else
    {
    /* when x is odd and y is even */
    y
    >>= 1;
    }
    }
    else
    {
    /* when x is even */
    if ( y & 0x1 )
    {
    /* when x is even and y is odd */
    x
    >>= 1;
    if ( x < y )
    {
    temp
    = x;
    x
    = y;
    y
    = temp;
    }
    }
    else
    {
    /* when x and y are both even */
    x
    >>= 1;
    y
    >>= 1;
    ++factor;
    }
    }
    }
    return ( x << factor );
    }
  • 相关阅读:
    题解:艾米利亚的魔法
    tarjan求割点
    集合删数
    小测题解
    [考试]20141028
    铺地毯
    [考试]20141027
    大家好
    【DM642学习笔记一】关于Can't Initialize Target CPU的一种解决方法 : Error 0x80000240
    iOS开发之获取系统相册ALAssetLibrary
  • 原文地址:https://www.cnblogs.com/bl4nk/p/2023055.html
Copyright © 2011-2022 走看看