线性筛法求质数
个人描述:
这也是一个用空间换时间的方法,速度固然是快,但是你要求多大上限的质数就需要多大上限的数组,这在一定程度上限制的大数的范围。有解决方法?留待以后闲时研究。
应用原理:
因式分解定理: 任何一个非质数都可以分解成质数的连乘积
即:合数 n = pkq (p < q)
因此在删除非质数时,如果已知p是质数,可以先删除p2, p3, p4....,接着找出比p大的而且没有被删除的数q,然后删除pq, p2q, p3q...,一直到pq > n为止。
代码示例:
#include <stdio.h> #include <stdlib.h> #define MAX_COUNT 10000 #define NEXT(x) x = next[x] #define PREV(x) x = prev[x] #define REMOVE(x) { next[prev[x]] = next[x]; \ prev[next[x]] = prev[x];} #define INIT(n) { unsigned long i; \ for(i = 2; i <= n; i++){ \ next[i] = i + 1; \ prev[i] = i - 1; \ } \ prev[2] = next[n] = NULL; \ }
int main(int argc, char** argv) { unsigned long num, count; unsigned long prime, factor, multi; unsigned long next[MAX_COUNT + 1]; unsigned long prev[MAX_COUNT - 1];
printf("%s", "please input the upper num\n"); scanf("%d", &num);
INIT(num);
for(prime = 2; prime * prime <= num; NEXT(prime)) { for(factor = prime; prime * factor <= num; NEXT(factor)) { for(multi = prime * factor; multi <= num; multi *= prime) { REMOVE(multi); } } } for(prime = 2, count = 0; prime != NULL; NEXT(prime)) { if(count++ % 8 == 0) { printf("\n"); } printf("%8ld", prime); } return 0; } |