转载自:http://blog.csdn.net/lxmky/article/details/7913885
问题:
求出所有1-MAX之间的素数
分析:
我们知道如何判断一个数是否为素数,判断number是否可以被1到sqrt(num)之间数整除,如果存在被整除的,不是素数,否则就是素数。
但是,如果用这种方法来计算,时间复杂度会非常高,我们采用另一种更好的方法——筛选法。
筛选法直观上比较好理解,从2开始,删除所有2*p(p>=2),然后再选取下一次没有被删除的数t,同样删除t*p(p>=2)的数,最后没有被删除的数就是我们要求的素数,这是直观上的理解,实际操作中可以有更多的优化,算法介绍参考链接:http://www.math.utah.edu/classes/216/assignment-07.html
算法代码如下:
include <iostream>
include <cstdlib>
include <cstdio>
include <ctime>
using namespace std;
define MAX 100000000
int main()
{
// int a[MAX + 1];
int *a = (int *)malloc((MAX + 1)*sizeof(int));
if(a == NULL)
{
cout << "create memory error!" <<endl;
return -1;
}
for (int i = 1; i <= MAX + 1; i++) //初始化
a[i] = 1;
int t = 0;
clock_t start = clock();
for (int j = 2; j <= MAX; j++)
{
if (a[j])
{
for (t = 2; t * j <= MAX; t++) //删除t*p,其中p>=2
{
a[t * j] = 0;
}
}
}
clock_t end = clock();
printf("Time is: %f\n", (double)(end - start)/CLOCKS_PER_SEC);
for (int i = 2; i <= 5000; i++)
if(a[i])
printf("%d ", i);
free(a);
return 0;
}
程序运行,1到1亿的数据,只需要8.24s,效率还是非常高。网上有更好的优化方法,但是思路还是一样的。
网上找到的更高效的算法,代码如下:
include <iostream>
include <cstdlib>
include <cstdio>
include <ctime>
using namespace std;
define MAX 100000000
int main()
{
// int a[MAX + 1];
int *a = (int *) malloc((MAX + 1) * sizeof(int));
if (a == NULL)
{
cout << "create memory error!" << endl;
return -1;
}
for (int i = 1; i <= MAX + 1; i++) //初始化
a[i] = 1;
int t = 0;
int j;
clock_t start = clock();
for (int i = 2; i * i <= MAX; i++)
{
if (a[i])
{
for (j = i * i; j <= MAX; j += i)
a[j] = 0;
}
}
clock_t end = clock();
printf("Time is: %f\n", (double) (end - start) / CLOCKS_PER_SEC);
for (int i = 2; i <= 5000; i++)
if (a[i])
printf("%d ", i);
free(a);
return 0;
}
程序运行时间是5.43s,这里优化的地方是j从i*i开始,而不是i*2开始。
总结:
素数求解使用简单、高效的思路,而且非常适合计算机实行。