计算素数算法的一些优化(编程珠玑阅读感想)

        这篇文章同样是关于我读编程珠玑的一些体会与感想,这是关于计算素数算法优化的一些感想。

        在学C语言的时候,用程序打印出某个范围内的所有素数的练习题大家都不陌生,我当时想到的算法类似下面这样的。

int prime(int n)
{
  int i;
  for(i=2;i<n;i++)
    if(n%i==0)
    return 0;
  return 1;
}
main()
{
  int i;
  int n=10000;
  for(i=2;i<=n;i++)
    if(prime(i))
      printf("%d\n", i);
}


 

        prime(n)用来检查n是否是素数,后来老师又介绍了另一种算法,如果一个数可以被n整除,那么它一定能被√n整除,所以把prime()函数里面的循环优化成这样。
for(i=2;i<=sqrt(n);i++)
        但是作者用性能监视工具发现第二种算法并没有比第一种算法快,反而慢了许多,原因是sqrt会占用很多的CPU时间,而for循环每次都要执行一次sqrt,这才导致了算法二变慢,所以把sqrt放到for()循环外面。
int m=sqrt(n);
for(i=2;i<=m;i++)
{····}

       但是作者还是觉得循环是累赘,有提供了下面的算法,思想大概是这样,对能被2、3、5整除的数进行检验,然后在将奇数作为可能因子(我怎么想不到大于2的偶数都不可能作为因子呢,笨···)。
int prime(int n)
{
  int i,m;
  if(n%2==0)
    return (n==2);
  if(n%3==0)
    return (n==3);
  if(n%5==0)
    return (n==5);
  m=sqrt(n);
  for(i=7;i<=m;i=i+2)
    if(n%i==0)
      return 0;
  return 1;
}

        后来作者考虑到sqrt比较费时,所以对循环做了如下修改(不得不佩服啊~)。
for(i=7;i*i<=n;i=i+2)

        看完之后想了想,如果在数据量相当大的情况下,用算法一不知道要花多少时间啊,根据作者的监测,当n=100000时,算法一由于时间太长没法给出具体数字,算法二用了近3000秒,而最后一种把开方换成乘法用了一分钟左右,当然这些时间数据是在作者机器上的运行时间。此时深刻体会到良好的算法设计可以大大提高程序的效率。

你可能感兴趣的:(算法,优化)