介绍
埃拉托斯特尼筛法,简称埃氏筛,也称素数筛。这是一种简单且历史悠久的筛法,用来找出一定范围内所有的素数。
所使用的原理是从2开始,将每个素数的各个倍数,标记成合数。一个素数的各个倍数,是一个差为此素数本身的等差数列。此为这个筛法和试除法不同的关键之处,后者是以素数来测试每个待测数能否被整除。
原理
给出要筛数值的范围n,找出√n以内的素数。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个素数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个素数5筛,把5留下,把5的倍数剔除掉;不断重复下去。
步骤
以25为例:
- 列出2以后的所有序列:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 标出序列中的第一个质数,也就是2,序列变成:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 将剩下序列中,划去2的倍数,序列变成:
- 2 3
45678910111213141516171819202122232425
- 2 3
- 如果现在这个序列中最大数小于等于最后一个标出的素数的平方,那么剩下的序列中所有的数都是质数,否则回到第二步。
算法
先输入要删选的范围数num
,创建长度为num+1
的数组prime[]
,使得prime[i]=i
(方便计算)。
再从小到大选列出素数 i :将素数的倍数标记为0:prime[i * j] = 0
;,判断此时素数的平方是否小于这个数组中的最大数if (getMax(prime, num) <= i * i)
,若是则继续挑选下一个素数,重复以上步骤;若否,则筛选完成,列出素数。
代码
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int getMax(int prime[], int index)
{
for (int i = index;; i--)
if (prime[i])
return prime[i];
}
int main()
{
int num;
printf("Enter a number greater than 1:");
do
{
scanf("%d", &num);
} while (num <= 1);
int prime[num + 1];
for (int i = 0; i <= num; i++)
prime[i] = i;
for (int i = 2;; i++)
if (prime[i]!=0){
for (int j = 2; i * j <= num; j++)
prime[i * j] = 0;
if (getMax(prime, num) <= i * i)
break;
}
else prime[i] = 0;
printf("Prime Numbers no more than %d are:\n", num);
for (int flag = 0, i = 2; i <= num; i++)
if (prime[i]){
printf("%d ", prime[i]);
flag++;
if (flag % 20 == 0)
printf("\n");
}
return 0;
}