输出不超过n的所有素数 (筛法)

来源:互联网 发布:webuploader java demo 编辑:程序博客网 时间:2024/05/29 04:48

O(nlogn) 的算法,还不错。

思想:

设置2为素数,然后划去所有2的倍数

然后查找2后面第一个没被划去的数(为3),然后知道3为素数,划去所有3的倍数

然后查找3后面第一个没被划去的数,由于4已经被划掉,所以下一个将会找到5,划去所有5的倍数...

以此类推

 

需要注意的三点是:

(1)遇到合数则跳过

(2)划去素数p的倍数时,从p*p开始划去,因为p*m (m < p)的数已经被划去了(它是m的最小质因子的倍数)

(3)由(2),在划去时,所有的大于 sqrt(n) 的素数都不用划去它的倍数,直接跳过


代码如下:


#include <stdio.h>#include <time.h>#include <math.h>#include <windows.h>inline int GetPrimes(int MAX_NUMBER){int start = clock();ULONG Count = 0;BYTE* List;List = new BYTE[MAX_NUMBER + 1];memset(List, 0x01, MAX_NUMBER + 1);int tmp = sqrt(MAX_NUMBER);//List[2] = 1;for (int i = 2; i <= MAX_NUMBER; i++) {if (List[i]) {Count++;//printf("%d ", i);if (i > tmp)   continue;   ULONG Buf = i * i;while (Buf <= MAX_NUMBER) {if (List[Buf]) {List[Buf] = 0;}Buf += i;}}}    int end = clock();printf("Count = %.8d, ", Count);printf("Running time = %dms.\n", end - start);free(List);return end - start;}#define TEST_COUNT       10int main(){int stime = 0;printf("MAX_NUMBER = %d\n", 1000000);for (int n = 0; n < TEST_COUNT; n++) {stime += GetPrimes(1000000);}printf("Average Time: %dms\n\n", stime / TEST_COUNT);stime = 0;printf("MAX_NUMBER = %d\n", 10000000);for (int n = 0; n < TEST_COUNT; n++) {stime += GetPrimes(10000000);}printf("Average Time: %dms\n\n", stime / TEST_COUNT);stime = 0;printf("MAX_NUMBER = %d\n", 100000000);for (int n = 0; n < TEST_COUNT; n++) {stime += GetPrimes(100000000);}printf("Average Time: %dms\n\n", stime / TEST_COUNT);return 0;}


做测试的结果还不错(难道是我的电脑比较好...):



0 0
原创粉丝点击