1、Bezout定理证明
构造集合
S = a m − b n : m , n ∈ Z 且 a m + b n ≥ 0 . S = {am − bn : m, n ∈ Z 且 am + bn ≥ 0}. S=am−bn:m,n∈Z且am+bn≥0.
在 S 中取最小正值 d = ar + bs
设 gcd(a, b) = q, 则 a = k1q, b = k2q, d = ar + bs = q(k1r + k2s)
∴ d | q 即有 d >= q①
令 p = ⌊a/d⌋, 则有 x = a mod d = a - pd = a - p(ar + bs) = a(1 - pr) + b(-ps)
∴ x 也是 a, b 的线性组合且 0<=x<s
由于 d 是 a, b 线性组合的最小正值, 所以 x = 0
∴ d | a , 同理 d | b
∴ d | q 即有 q>=d②
由①②可得 d = q 即 gcd(a,b) = ar + bs
2、GCD算法的迭代版本
int gcd(int a,int b){
int temp;
while(b){
temp=a%b;
a=b;
b=temp;
}
return a;
}
3、EGCD算法
#include<stdio.h>
#include<math.h>
int mat[256][3];
void egcd(int a,int b,int *r,int *s,int *d){
int t;
if(a<b){
t=a;
a=b;
b=t;
}
mat[0][0]=1;mat[0][2]=a;
mat[1][1]=1;mat[1][2]=b;
mat[2][0]=1-0;mat[2][1]=0-a/b;mat[2][2]=a%b;
t=2;
while(mat[t-1][2]%mat[t][2]){
t++;
mat[t][0]=mat[t-2][0]-(mat[t-2][2]/mat[t-1][2])*mat[t-1][0];
mat[t][1]=mat[t-2][1]-(mat[t-2][2]/mat[t-1][2])*mat[t-1][1];
mat[t][2]=mat[t-2][2]%mat[t-1][2];
}
*r=mat[t][0];
*s=mat[t][1];
*d=mat[t][2];
}
int main(){
int a,b,r,s,d;
scanf("%d%d",&a,&b);
egcd(a,b,&r,&s,&d);
printf("r=%d,s=%d,d=%d",r,s,d);
return 0;
}
批处理版本的GCD算法
#include<stdio.h>
int gcd(int a,int b){
int temp;
while(b){
temp=a%b;
a=b;
b=temp;
}
return a;
}
int bat_gcd(int a[],int len){
int temp=a[0];
for(int i=1;i<len;i++){
temp=gcd(temp,a[i]);
}
return temp;
}
int main(){
int a[6]={
63,21,49,42,56,35};
int len=sizeof(a)/sizeof(int);
printf("%d",bat_gcd(a,len));//输出7
return 0;
}