在高斯想出1+...+100那个算法之前,他老师是一遍遍循环把1到100的和计算出来的。以下是比较的普通算法与高斯算法的不同,其中gettime()是获取当前的毫秒数。
#include<stdio.h>
#include<time.h>
#include "mytime.h"
long normal(int max); //普通算法 从1加到100
long gaosi(int max); //高斯算法 从1加到100
int main(void)
{
int max = 100;
printf("输入从1加到多少:");
scanf("%d",&max);
long t1=normal(max);
printf("total:%ldms\n",t1);
long t2=gaosi(max);
printf("total:%ldms\n",t2);
return 0;
}
long normal(int max)
{
long s1 = gettime();
int i = 0;double sum = 0;
for(i=1;i<=max;i++)
{
sum += i;
}
printf("normal --> %.0f\n",sum);
long s2 = gettime();
return s2 - s1;
}
long gaosi(int max)
{
long s1 = gettime();
int i=0;double sum = 0;
sum = (1 + (double)max)/2 * max;
printf("gaosi --> %.0f\n",sum);
long s2 = gettime();
return s2 - s1;
}
对于两个算法,在测试时为了避免数值过大溢出,使用了double计算和,而在高斯算法中,为避免(1+max)*max/2时会首先过大,所以先计算的/2再*max
算法分析:
算法的核心在于普通的循环加和与高斯的运算公式,前者的计算次数会随着max的变化而线性变化,而后者不会,因此前者的时间复杂度为O(n),而后者是O(1)
实际测试:
[yanhua@localhost chap02]$ gcc gaosi.c mytime.c -o a.out
[yanhua@localhost chap02]$ ./a.out
输入从1加到多少:10000
normal --> 50005000
total:0ms
gaosi --> 50005000
total:0ms
[yanhua@localhost chap02]$ ./a.out
输入从1加到多少:100000
normal --> 5000050000
total:0ms
gaosi --> 5000050000
total:0ms
[yanhua@localhost chap02]$ ./a.out
输入从1加到多少:1000000
normal --> 500000500000
total:5ms
gaosi --> 500000500000
total:0ms
[yanhua@localhost chap02]$ ./a.out
输入从1加到多少:10000000
normal --> 50000005000000
total:39ms
gaosi --> 50000005000000
total:0ms
由运行结果看,参数越大,越能看出高斯算法的优势。