个人描述

这也是一个用空间换时间的方法,速度固然是快,但是你要求多大上限的质数就需要多大上限的数组,这在一定程度上限制的大数的范围。有解决方法?留待以后闲时研究。

应用原理

因式分解定理: 任何一个非质数都可以分解成质数的连乘积

即:合数 n = pkq (p < q)

因此在删除非质数时,如果已知 p 是质数,可以先删除 p2, p3, p4….,接着找出比 p 大的而且没有被删除的数 q,然后删除pq, p2q, p3q…,一直到 pq > n为止。

代码示例:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX_COUNT 10000
  4. #define NEXT(x) x = next[x]
  5. #define PREV(x) x = prev[x]
  6. #define REMOVE(x) { next[prev[x]] = next[x]; \
  7. prev[next[x]] = prev[x];}
  8. #define INIT(n) { unsigned long i; \
  9. for(i = 2; i <= n; i++){ \
  10. next[i] = i + 1; \
  11. prev[i] = i - 1; \
  12. } \
  13. prev[2] = next[n] = NULL; \
  14. }
  15. int main(int argc, char** argv)
  16. {
  17. unsigned long num, count;
  18. unsigned long prime, factor, multi;
  19. unsigned long next[MAX_COUNT + 1];
  20. unsigned long prev[MAX_COUNT - 1];
  21. printf("%s", "please input the upper num\n");
  22. scanf("%d", &num);
  23. INIT(num);
  24. for(prime = 2; prime * prime <= num; NEXT(prime))
  25. {
  26. for(factor = prime; prime * factor <= num; NEXT(factor))
  27. {
  28. for(multi = prime * factor; multi <= num; multi *= prime)
  29. {
  30. REMOVE(multi);
  31. }
  32. }
  33. }
  34. for(prime = 2, count = 0; prime != NULL; NEXT(prime))
  35. {
  36. if(count++ % 8 == 0)
  37. {
  38. printf("\n");
  39. }
  40. printf("%8ld", prime);
  41. }
  42. return 0;
  43. }

备注