时间复杂度小的 求两个整数的最大公约数

简单回顾一下时间复杂度:

  一个算法是由控制结构(顺序、分支和循环三种)和原操作(指固有数据类型的操作)构成的,则算法时间取决于两者的综合效果。

为了便于比较同一问题的不同算法,通常的做法是,从算法中选取一种对于所研究的问题(或算法类型)来说是基本操作的原操作,以

该基本操作重复执行次数作为算法的时间量度。

最近刷一道PAT的题目时,总有两个测试点超时,原来是自己的代码时间复杂度太大了。撰写此文,谨记!

求两个整数的最大公约数。

一:辗转相除法(欧几里德算法  出自几何原本)

基本原理和证明不在这里考究证明,(感觉其实是证明了gcd(a,b)=gcd(b,r),r是a mod b的结果)有兴趣的可以看看百度百科。辗转相除法

 1 int gcd0(int a,int b)    //辗转相除法接地气的一种写法
 2 {
 3     int r=1;
 4     while(r!=0)
 5     {
 6         r=a%b;
 7         a=b;
 8         b=r;
 9     }
10     return a;
11 } 
12 int gcd(int a,int b)    //辗转相除法高大上的一种写法 
13 {
14     return (b>0)?gcd(b,a%b):a;
15 }
View Code

二:更相减损法 (出自《九章算术》)

 1 int gcd3(int a,int b)    //更相减损法
 2 {
 3     int n=1;        //存储第一步中约掉的若干个2  1代表2^0 即0个2 
 4     int ans;        //存储最终返回的结果
 5     while(a%2==0&&b%2==0)
 6     {
 7         a/=2;b/=2;n*=2;
 8     } 
 9     while(a!=b)
10     {
11         if(a>b)
12             a-=b;
13         else
14             b-=a;
15     }
16     ans*=a*n;
17     return ans;
18 } 
View Code

一下是总结的三种求最大公约数的三种方法的代码

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int gcd0(int a,int b)    //穷举法 
 5 {
 6     int i;
 7     for(i=min(a,b);i>0;i--)
 8     {
 9         if(a%i==0&&b%i==0)
10             break;
11     }
12     return i;
13 }
14 
15 int gcd1(int a,int b)    //辗转相除法接地气的一种写法
16 {
17     int r=1;
18     while(r!=0)
19     {
20         r=a%b;
21         a=b;
22         b=r;
23     }
24     return a;
25 } 
26 int gcd2(int a,int b)    //辗转相除法高大上的一种写法 
27 {
28     return (b>0)?gcd2(b,a%b):a;
29 }
30 
31 int gcd3(int a,int b)    //更相减损法
32 {
33     int n=1;        //存储第一步中约掉的若干个2  1代表2^0 即0个2 
34     int ans;        //存储最终返回的结果
35     while(a%2==0&&b%2==0)
36     {
37         a/=2;b/=2;n*=2;
38     } 
39     while(a!=b)
40     {
41         if(a>b)
42             a-=b;
43         else
44             b-=a;
45     }
46     ans*=a*n;
47     return ans;
48 } 
49 
50 int main()
51 {
52     int a,b;
53     printf("请输入两个整数:");
54     scanf("%d%d",&a,&b);
55     cout<<gcd3(a,b)<<endl;
56     cout<<gcd0(a,b)<<endl;
57     return 0;
58 }

猜你喜欢

转载自www.cnblogs.com/ManOK/p/10290052.html