Stein算法

Stein算法主要用于解决超大数取模给欧几里得算法带来局限的问题。

Stein递归算法步骤:Stein(A,B);

1).调整A、B使A>B

2)若A、B都是偶数,则记录下公因子2,然后return 2*Stein(A>>1,B>>1);

3)若A为奇数B为偶数,则return Stein(A,B>>1);

   若B为奇数A为偶数,则return Stein(A>>1,B);

4)若两个都为奇数,则return Stein(abs(A-B),B);

理由:设在某一次过程中A、B的最大公因子为D,可得A=k*D,B=h*D;(A>B -> k>h);  所以A-B=|k-h|*D。A,B都为奇数,有奇偶数乘积奇偶性可得D,k,h都为奇数。所以|k-h|一定是偶数,与h互质,所以A-B与B的最大公因数依旧为D。递归成立!

临界条件:if(B==0)return A;

代码:

#include<cstdio>
#include<algorithm>
using namespace std;

int stein(int a,int b){
    if(a<b)swap(a,b);
    if(b==0)return a;
    if((a&1)==0&&(b&1)==0)return stein(a>>1,b>>1)<<1;
    else if(a&1&&(b&1)==0)return stein(a,b>>1);
    else if(b&1&&(a&1)==0)return stein(a>>1,b);
    else return stein(a-b,b);
}

int main(){
    printf("%d",stein(18,12));
    return 0;
}
咳咳,有件事必须说一下:严格意义上来说,负数和正数之间是没有公因子这一说的【因子要大于0】,但是如果非要求他们的正因子【负因子】,可以先把两个数取绝对值,stein之后再加个符号即可。

猜你喜欢

转载自blog.csdn.net/qq_39304630/article/details/81482983