辗转相除法Euclid(欧几里德)

转载 2012年03月22日 20:16:03

基本算法——辗转相除法

问题:输出两个正整数a,b,0<a<b, 输出其最大公约数p和最小公倍数q

解法1——

pa开始,检测p是否能同时整除ab, 是则停止循环,不是则令p1,继续检测。

qb开始,检测q是否能同时被ab整除,是则停止循环,不是则令q1,继续检测。

源程序1

#include <stdio.h> 
void main() 

  int a,b, p, q
  do{

printf("请输入ab:\n");   scanf("%d%d",&a,&b); 

} while ( a<0 || b<0 || a>b); 

p=a;

while( a%p!=0 || b%p!=0) p--;

printf("这两个数的最大公约数是%d\n",p); 

q=b;

while( q%a!=0 || q%b!=0) q++;

printf("这两个数的最小公倍数是%d\n",q); 
}

改进——已知整数a,b及其最大公约数p,则直接可推算出最小公倍数q

q= a*b/p;

源程序2

#include <stdio.h> 
void main() 

  int a,b, p, q
  do{

printf("请输入ab:\n");   scanf("%d%d",&a,&b); 

} while ( a<0 || b<0 || a>b); 

p=a;

while( a%p!=0 || b%p!=0) p--;

printf("这两个数的最大公约数是%d\n",p); 

q= a*b/p;

printf("这两个数的最小公倍数是%d\n",q); 
}

解法1的缺点:效率低。

例如a=1397, b=2413,其最大公约数p=127,为得到p,共循环了1397-127+1=1171次。

如何提高效率?

解法2——辗转相除法,在西方称为Euclid(欧几里)算法。

计算(13972413的最大公约数为例:

以大数2413为被除数,以小数1397为除数相除商为1余数为1016

以除数1397为被除数余数1016,相除得:  商为1余数为381

以除数1016为被除数,以余数381为除数, 相除得:   商为2余数为254

以除数381为被除数,以余数254为除数,  相除:  商为余数为127

以除数254为被除数以余数127为除数,相除得:  商为2余数为

~~发现能整除127就是最大公约数。整个计算过程为: 

被除数b

除数a

s

余数r

2413

1397

1

1016

1397

1016

1

381

1061

381

2

254

381

254

1

127

254

127

2

0

数学证明:  b=as+r (0≤r ≤b-1),且a,b的最大公约数用符号a,b代表 

r=0,显然(a,b=a; 

r≠0, 由于b=as+r,每个能整除a,r的整数都能整除bà能同时整除a,b, 故有

(a,r) | (a,b)

另一方面,r=b-aq 每个能整除a,b的整数都能整除r à能同时整除a,r, 故有

(a,b) | (a,r) 

因此a,b=(a,r)

辗转相除法程序
#include <stdio.h> 
void main() 

int a,b,r, m
do{

printf("请输入ab:\n"); 
scanf("%d%d",&a,&b); 
}while( a<0 || b<0 ||a>b);

m=a*b; 

do
 r=b%a
 b=a;

a=r;  

}while(r!=0);  

printf("这两个数的最大公约数是%d\n",r); 

printf("这两个数的最小公倍数是%d\n", m/r);  //不能写“a*b/r

} ==========================================================================

#include <stdio.h>
int gac(int a,int b);
void main()
{
 int a,b,temp;
 printf("请输入两个整数:\n");
 scanf("%d%d",&a,&b);
 temp=gac(a,b);
 printf("最大公约数为:%d\n",temp);
}
int gac(int a,int b){
 if(a<b)
  return gac(b,a);
 if(a%b!=0)
  gac(b,a%b);
 else
  return b;
}

==============================================================================================================================

输入有多组测试案例。
每个测试案例为1行,全由小写英文字母组成,长度不超过100,000。

输出:

对应每个测试案例,输出最大压缩串,单独占1行。

样例输入:
aaaa
xyz
abababab
abcabcabdabd
样例输出:
a4
xyz1
ab4
abcabcabdabd1
提示:
案例4中,答案不是abc2abd2,因为描述中提过压缩串仅是将原始串完全恰好的分割为一个字符串和数字的形式,因此只能为abcabcabdabd1

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define STRING_LENGTH 100001
int gcd(int a,int b){
    int r;
    while( (r=a%b)!=0){
  a=b;
  b=r;
    }
    return b;
}
int recur(char *sz,int n){
    int len,i;
    len=strlen(sz);
    if(len%n!=0)return 0;
    for(i=n;i<len;i+=n)
  if(strncmp(sz,sz+i,n)!=0)
   return 0;
  return 1;
}

char sz[STRING_LENGTH];
int cnt[26];
int main(){
    int len,i,d,n;
 while(gets(sz)){
  len=strlen(sz);
  memset(cnt,0,sizeof(cnt));
  
  for(i=0;i<len;i++)cnt[sz[i]-'a']++;
  
  i=0;
  while(i<26&&cnt[i]==0)i++;
  d=cnt[i];
  while(i<26)d=gcd(cnt[i++],d);
  
  for(n=len/d;n<=len/2;n+=len/d)
   if(len%n==0&&recur(sz,n)==1)break;
   if(n>len/2)n=len;
   
   sz[n]='\0';
   printf("%s%d\n",sz,len/n);
    }
    return 0;
}

 

 


 

扩展欧几里德算法 递归和非递归实现及证明

关于欧几里得算法,贝祖等式,扩展欧几里得算法,Wikipedia的解释非常非常详细了。 另外,看了好多别人优秀的总结,我认为最详尽的就是ACM之家的总结。 这里自己再总结一次…实际上就是把别人...
  • yoer77
  • yoer77
  • 2017年04月07日 16:19
  • 2670

欧几里得算法(即辗转相除法)的时间复杂度

欧几里得算法(即辗转相除法)的时间复杂度 本文是参考新浪博客而写。 欧几里得算法, 又称辗转相除法, 用于求两个自然数的最大公约数. 算法的思想很简单, 基于下面的数论等式 ...
  • xiamentingtao
  • xiamentingtao
  • 2015年03月28日 16:56
  • 3130

辗转相除法(欧几里德算法)原理

原理: 假设有两个数x和y,存在一个最大公约数z=(x,y),即x和y都有公因数z, 那么x一定能被z整除,y也一定能被z整除,所以x和y的线性组合mx±ny也一定能被z整除。(m和n可取任意整数...
  • hanghangde
  • hanghangde
  • 2017年03月19日 12:35
  • 584

欧几里得辗转相除法证明及推论

一、辗转相除法定义辗转相除法:以大数除以小数,如果能整除,那么小数就是所求的最大公约数(Greatest CommonDivisor:gcd)。否则就用余数来除刚才的除数;再用这新除法的余数去除刚才的...
  • so_geili
  • so_geili
  • 2017年02月10日 16:21
  • 841

扩展欧几里德(顺带说一下取模)

扩展欧几里德定律:  对于不完全为0的非负整数a,b,gcd(a, b)表示a, b的最大公约数,必定存在整数对x,y,满足a*x+b*y==gcd(a, b)。 证明:(转) a*x1+b*y1...
  • tree__water
  • tree__water
  • 2016年08月03日 23:47
  • 2836

计算最大公约数的两种算法:辗转相除法和Stein算法

欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理: 定理:gcd(a,b) = gcd(b,a mod b) 其算法用C++语言描述为: in...
  • highyyy
  • highyyy
  • 2011年04月11日 13:36
  • 871

欧几里德 和 拓展欧几里德算法

一.欧几里德欧几里德是用来求最大公约数的算法 其算法的中心思想为: 设a,b的最大公约数为c,则c一定也是a%b的最大公约数 证明方法很多,下面列出最简单的一个: 令 :a = xc; ...
  • WuBaizhe
  • WuBaizhe
  • 2017年05月22日 17:53
  • 293

证明欧几里德(辗转相除法)算法

             ---《百科》证明的很好,直接Copy过来了、
  • zzti_xiaowei
  • zzti_xiaowei
  • 2018年02月07日 09:55
  • 24

欧几里德求最大公约数(辗转相除法)

定理:Gcd(m,n)=Gcd(n,m mod n) 证明:对于任何正整数a,b。如果a>b,都有a=k*b+r 即r=a-k*b => r=a mod b. 假设d为a,b的公约数,则a=a1*d,...
  • ccDLlyy
  • ccDLlyy
  • 2016年11月16日 13:35
  • 291
收藏助手
不良信息举报
您举报文章:辗转相除法Euclid(欧几里德)
举报原因:
原因补充:

(最多只允许输入30个字)