上篇 Algorithm in C(1) 中,只是实现了减法来求GCD的实现,下面的例子中使用三种方法来实现求GCD,并且加入了时间测定方法。
原例子取自韩文的《通过C语言学习算法》,原例是在Windows下实现的代码,我将它稍微改动了一下,以适用我的Linux系统。
Code
/* Implementation of Euclid's algorithm1 */
/* Programmed by Lee jaekyu */
/* Modified by Jin rize */
#include <stdio.h>
#include <sys/time.h>
//作10万次运算
#define LOOP 100000
//linux下的时间测定方法
long timecacul () {
struct timeval tv;
struct timezone tz;
gettimeofday(&tv,&tz);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
//使用减法
int gcd_minus(int u, int v)
{
int t;
while(u)
{
if (u<v)
{
t=u; u=v; v=t;
}
u=u-v;
}
return v;
}
//使用取余
int gcd_modulus (int u, int v)
{
int t;
while(v)
{
t=u%v;
u=v;
v=t;
}
return u;
}
//使用递归
int gcd_recursion(int u, int v)
{
if (v==0)
return u;
else
return gcd_recursion(v, u%v);
}
void main(void)
{
int u,v, gcd;
long starttime, endtime;
int i;
puts ("\n EUCLID : Get GCD with time checking"
"\n Input 0 to end program ");
while(1)
{
puts ("\n Iput two positive integer ");
scanf("%d %d", &u,&v);
if (u<0 ||v<0)
continue;
if (u==0 || v==0)
break;
//测定时间
starttime=timecacul();
for (i=0; i<LOOP; i++)
gcd=gcd_minus(u,v);
endtime=timecacul();
printf("\n Minus methods : GCD of %d and %d is %d. in %ld ms.", u, v, gcd, endtime-starttime);
starttime=timecacul();
for (i=0; i<LOOP; i++)
gcd=gcd_modulus(u,v);
endtime=timecacul();
printf("\n Modulus methods : GCD of %d and %d is %d. in %ld ms.", u, v, gcd, endtime-starttime);
starttime=timecacul();
for (i=0; i<LOOP; i++)
gcd=gcd_recursion(u,v);
endtime=timecacul();
printf("\n Recursion methods : GCD of %d and %d is %d. in %ld ms.", u, v, gcd, endtime-starttime);
}
}
/* Implementation of Euclid's algorithm1 */
/* Programmed by Lee jaekyu */
/* Modified by Jin rize */
#include <stdio.h>
#include <sys/time.h>
//作10万次运算
#define LOOP 100000
//linux下的时间测定方法
long timecacul () {
struct timeval tv;
struct timezone tz;
gettimeofday(&tv,&tz);
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
//使用减法
int gcd_minus(int u, int v)
{
int t;
while(u)
{
if (u<v)
{
t=u; u=v; v=t;
}
u=u-v;
}
return v;
}
//使用取余
int gcd_modulus (int u, int v)
{
int t;
while(v)
{
t=u%v;
u=v;
v=t;
}
return u;
}
//使用递归
int gcd_recursion(int u, int v)
{
if (v==0)
return u;
else
return gcd_recursion(v, u%v);
}
void main(void)
{
int u,v, gcd;
long starttime, endtime;
int i;
puts ("\n EUCLID : Get GCD with time checking"
"\n Input 0 to end program ");
while(1)
{
puts ("\n Iput two positive integer ");
scanf("%d %d", &u,&v);
if (u<0 ||v<0)
continue;
if (u==0 || v==0)
break;
//测定时间
starttime=timecacul();
for (i=0; i<LOOP; i++)
gcd=gcd_minus(u,v);
endtime=timecacul();
printf("\n Minus methods : GCD of %d and %d is %d. in %ld ms.", u, v, gcd, endtime-starttime);
starttime=timecacul();
for (i=0; i<LOOP; i++)
gcd=gcd_modulus(u,v);
endtime=timecacul();
printf("\n Modulus methods : GCD of %d and %d is %d. in %ld ms.", u, v, gcd, endtime-starttime);
starttime=timecacul();
for (i=0; i<LOOP; i++)
gcd=gcd_recursion(u,v);
endtime=timecacul();
printf("\n Recursion methods : GCD of %d and %d is %d. in %ld ms.", u, v, gcd, endtime-starttime);
}
}
运行结果如下:
Code
EUCLID : Get GCD with time checking
Input 0 to end program
Iput two positive integer
280 30
Minus methods : GCD of 280 and 30 is 10. in 6 ms.
Modulus methods : GCD of 280 and 30 is 10. in 3 ms.
Recursion methods : GCD of 280 and 30 is 10. in 3 ms.
Iput two positive integer
12 9
Minus methods : GCD of 12 and 9 is 3. in 3 ms.
Modulus methods : GCD of 12 and 9 is 3. in 2 ms.
Recursion methods : GCD of 12 and 9 is 3. in 3 ms.
Iput two positive integer
2980 20
Minus methods : GCD of 2980 and 20 is 20. in 64 ms.
Modulus methods : GCD of 2980 and 20 is 20. in 1 ms.
Recursion methods : GCD of 2980 and 20 is 20. in 2 ms.
Iput two positive integer
EUCLID : Get GCD with time checking
Input 0 to end program
Iput two positive integer
280 30
Minus methods : GCD of 280 and 30 is 10. in 6 ms.
Modulus methods : GCD of 280 and 30 is 10. in 3 ms.
Recursion methods : GCD of 280 and 30 is 10. in 3 ms.
Iput two positive integer
12 9
Minus methods : GCD of 12 and 9 is 3. in 3 ms.
Modulus methods : GCD of 12 and 9 is 3. in 2 ms.
Recursion methods : GCD of 12 and 9 is 3. in 3 ms.
Iput two positive integer
2980 20
Minus methods : GCD of 2980 and 20 is 20. in 64 ms.
Modulus methods : GCD of 2980 and 20 is 20. in 1 ms.
Recursion methods : GCD of 2980 and 20 is 20. in 2 ms.
Iput two positive integer
翻译一下作者的原话:
280, 30 的情况:
取余算法最快,算法相同的情况下,递归实现稍慢(在我的运行结果中是一样的,怪我机子还不错。)
12, 9的情况:
因为两个数太接近,需要进行的减法运算也少,所以数字都比较接近。
2980, 20的情况:
要做接近150次的减法运算,所以利用减法的算法耗时最长,取余算法则显示出了优越性