欧几里德最大公约数算法正确性的一次简单分析

依旧先摆出算法代码:

   1:  int get_common_divisor(int a,int b)
   2:  {
   3:      int x=a;
   4:      int y=b;
   5:      int m=0;
   6:   
   7:      while(y>0)
   8:      {
   9:          m=x%y;
  10:          x=y;
  11:          y=m;
  12:      }
  13:   
  14:      return x;
  15:  }

欧几里德求最大公约数的原理为:

计A,B两数最大公约数为Gcd(A,B),则Gcd(A,B)=Gcd(B,A Mod B)=Gcd(A Mode B,B Mod (A Mod B))… 公式(1)

即两数的最大公约等于第二数和两数余数的最大公约,其值为公式(1)循环最后余数为0之前的那次余数值。

现在给出命题:

求证欧几里德求最大公约数的正确性。

证明:

只讨论A>B的情形,因为B>A时将在第一次模运算之后(line 9)将二者位置翻转,仍然变成符合x>y的情形。

一种很明显的情形是A是B的倍数,则B显然是最大公约数,这符合Gcd(A,B)=Gcd(B,0)=B,这里利用了一个定理:任何数都是0的公约数。

现把A与B的求余运算改成形式A=Bk+m,显然此处默认B>m求k>=1.   记为公式(2)

不妨取A,B最大公约数存在且为G.则A,B分别可以写成含最大公约数的因式A=G*T1,B=G*T2; 记为公式(3)

公式(3)代入公式(2),A=Bk+m推导出G*T1=G*T2*k+m, m=G*(T1-T2*k); 显然我们得出一个结论:余数m必然包含最大公约数G,

每一次循环求余都将导致下一次的余数在不断减小,这是一个必然的事实,而另一个事实是余数若不呗整除则必然是正整数并渐小,而正整数的余数渐小若一直没有被整除则必然趋于1,而1能被任何数整除也是任何数的公约数,如果该减小的余数在某一步被整除了,则这个余数恰是自己和被除数的最大公约数,也即A,B的最大公约数。

不妨另循环求余中所有的余数取值为{m1,m2,…,mk,0},很显然由上述推理mk就是我们所要求的最大公约数。

posted @ 2012-06-17 13:32  Dance With Automation  Views(254)  Comments(0Edit  收藏  举报