最大公约数算法

1.最简单的做法无过于辗转相除法,即gcd( a, b ) = gcd( a, a%b ) 。
简单证明如下:
    设k是a,b的公因子,则k|a,k|b,由于r = a%b,即a = n*b + r ,由k|a,k|b,则k|r,则k是a, r的公因子。
    设k是a,r的公因子,则k|a,k|r,由a=n*b+r知k|b,则k是a,b的公因子。

具体程序如下(c++)
template< typename T >
T gcd( T a, T b )
{
    while ( b != 0 )
    {
        T r = a % b ; 
        a = b ; 
        b = r ;
    }
    return a ;
}

2.Stein算法
其基本原理如下:(设最大公约数为d,需要递归的地方用An、Bn、Dn表示)
1)假如a=0,则d=b
2)假如b=0,则d=a
3)假如2|a&&2|b,则2是公约数,取A1=a/2,B1=b/2,D1=2d(An+1=An/2, Bn+1=Bn/2, Dn+1=Dn*2)
4)假如2|a&&b不是偶数,则2不是公约数,于是An+1 = An/2, Bn+1 = Bn, Dn+1 = Dn
5) 假如2|b&&a不是偶数,则2不是公约数,于是An+1 = An, Bn+1 = Bn/2, Dn+1 = Dn
6)假如a,b都不是偶数,则An+1 = |An-Bn|, Bn+1 = min(An,Bn),Dn+1 = Dn,即gcd(|An-Bn|, min(An,Bn)) = gcd(An,Bn),证明方法同辗转相除法中用到的方法。
简单的实现如下:
template< typename T >
T stein_gcd( const T& a, const T& b )
{
 if ( a == 0 )
 {
  return b ;
 }
 else if ( b == 0 )
 {
  return a ;
 }
 else if ( a%2 == 0 && b%2 == 0 )
 {
  return 2 * stein_gcd(a/2,b/2) ;
 }
 else if ( a%2==0 && b%2!=0 )
 {
  return stein_gcd( a/2, b ) ;
 }
 else if ( a % 2 != 0 && b % 2 == 0 )
 {
  return stein_gcd( a, b/2 ) ;
 }
 else
  return stein_gcd( max(a,b)-min(a,b), min(a,b) ) ;
}
简单的递归,总感觉算法不够理想化,期望以后能够加以改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值