《编程珠玑》上的一道题,试着做了个小实验。
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "time.h"
#define N 100000000
//int gcd(int a, int b)
//{
// int tmp;
// while(b != 0)
// {
// tmp = b;
// b = a % b;
// a = tmp;
// }
// return a;
//}
int gcd(int a, int b)
{
while( a!= 0)
{
if(a>=b) a-=b;
else
{
int t=a;
a=b;
b=t;
}
}
return b;
}
void f1(int a[], int n, int rdist)
{
int i,k,t;
int prev;
//printf("gcd=%d\n",gcd(n,rdist));
for (i = 0; i < gcd(n,rdist); i++)
{
t = a[i];
prev = i;
while(1)
{
k = (prev + rdist) % n;
if(k == i) break;
a[prev] = a[k];
prev = k;
}
a[prev] = t;
}
}
void reverse(int a[], int start, int end)
{
int i, tmp;
int n = (end+start)/2;
for(i = start; i <= n; i++)
{
tmp = a[i];
a[i] = a[start+end-i];
a[start+end-i] = tmp;
}
}
void f2(int a[], int n, int rdist)
{
reverse(a, 0, rdist-1);
reverse(a, rdist, n-1);
reverse(a, 0, n-1);
}
int main()
{
int i;
int *a = (int *)malloc(sizeof(int)*N);
double duration;
clock_t start, finish;
for (i = 0; i < N; i++)
a[i] = i;
printf("start rotate...\n");
for (i = 1; i <= 20; i++)
{
start = clock();
f1(a,N,pow(2,i));
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration );
}
printf("\n------\n");
for (i = 1; i <= 20; i++)
{
start = clock();
f2(a,N,pow(2,i)); ;
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration );
}
return 0;
}
利用matplotlib画图:
#coding:utf-8
import matplotlib.pyplot as plt
import matplotlib as mpl
time1=[0.984000, 0.993000,1.008000,1.253000,1.820000,1.924000, 1.560000,1.606000,1.686000,1.883000,1.650000,1.901000,2.124000,2.333000,2.760000,2.767000,3.152000,2.845000,2.926000,2.778000]
time2=[0.139000,0.144000,0.149000,0.146000,0.147000,0.143000,0.149000,0.146000,0.151000,0.146000,0.151000,0.142000,0.153000,0.144000,0.147000,0.149000,0.152000,0.141000,0.150000,0.148000]
x = [2**(i+1) for i in range(len(time1))]
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
plt.plot(x,time1)
plt.plot(x,time2)
plt.xlabel(u'循环左移步数')
plt.ylabel(u'时间消耗(秒)')
plt.legend((u'杂技算法', u'翻转算法'))
plt.title(u'杂技算法和翻转算法效率对比')
plt.show()
最终对比: