如果是在小范围内如1到200,使用普通判断素数的方法就行了
C语言经典之判断素数
严格的说这只是挨个判断一个区间内的数是否是素数,不能算是筛选出素数,当区间范围很大.这种方法花费的时间是无法忍受的
如何求一段区间内的素数呢?我们可以将这个区间内的合数完全剔除掉,
注意一个合数C(composite)总能写成一个素数P(prime)和其他任意数O(other)的乘积
C=P∗O C = P ∗ O
例如要求出[2,25]内的素数
我们先找出最小的素数 2
将2组成的合数剔除掉,例如
2*2__2*3__2*4__2*5 ……
留下来的序列是: 2__3__5__7__9__11__13__15__17__19__21__23__25
留下最近的一个未被剔除的数(肯定是素数) 是 3
那么我们再将3组合成的合数剔除掉
3*2__3*3__3*4__3*5 ……
筛选到什么时候结束呢?
第一种方案 很自然地想到筛选到最后一个数为止
其实不必这么麻烦,
例如当我们将上面这个序列筛到5的时候
序列变成2__3__5__7__11__13__17__19__23
我们考察序列中 最大的一个数的开方
√23 √ 23 若假设23可以被某两个数 d1,d2 d 1 , d 2 整除,那么这两个数分布肯定是这样的
回过头来,我们已经提出了2,3,5所有的合数,也就是
C=2∗O C = 2 ∗ O , C=3∗O C = 3 ∗ O , C=5∗O C = 5 ∗ O
而最大的数23若能被 d1,d2 d 1 , d 2 整除
就可以写成
23=d1∗O 23 = d 1 ∗ O
那么 d1<√23<5 d 1 < √ 23 < 5
d1<5 d 1 < 5 的话肯定就会被 2,3,5组成的合数剔除掉
换句话说
23要是合数,肯定会被√23之前的某个数找到,如果√23之前都找不到,那么√23以后的数就不用找了.
而且
序列中最大的数23都找不到了,那么比23还小的数(13__17__19)就肯定也找不到了了
综上所述,整个递增序列只需找到 √n √ n 即可
#include
#include
#define range 99999
int main()
{
int i;
int j;
int check[range] = { 0 };// 0代表是素数
for (i = 2; i*i< range; i++)//C=P*O;sqrt range 左边筛完 右边就肯定找不到了
{
if (!check[i])//如果是素数才进行剔除它组成的合数
{
for (j = 2 * i; j < range; j += i)
{
check[j] = 1;//剔除素数组成的合数
}
}
}
for (i = 2; i < range; i++)
{
if (check[i] == 0)//打印留下来的素数
{
printf("%d ", i);
}
}
getchar();
}
这个方法有个坏处是某些合数会被重复的剔除
例如6 会被 2∗3,3∗2 2 ∗ 3 , 3 ∗ 2 剔除两次
#include
#include
int main()
{
int i;
int j;
int prime[range] = { 0 };
int check[range] = { 0 };
int primes = 0;
for (i = 2; i < range; i++)
{
if (!check[i])
{
prime[primes++] = i;
}
for (j = 0; j < primes && i*prime[j] < range; j++)
{
check[i*prime[j]] = 1;//合数可以化为合数and素数的乘积
if (!i%prime[j])//储存在prime[j]中的素数都是升序的
{
break;
}
}
}
这里还是利用了 C=i∗P C = i ∗ P 这一公式
即:合数=任意一数✖
素数
但是保证不重复筛选,我们可以把公式写成
C=i∗Pmin C = i ∗ P m i n
即此合数=任意一数*最小素因子
例如:12=4*3
我们可以写成12=6*2;
看程序
当 i=4的时候
会筛掉 4*2,
由于 i%prime[j]是4%2=0了;
所以此时并不会执行4*3
12这个合数只会在
12=6(i)*2(最小素因子)的时候被剔除;
我们得出了所有合数都只会在最小素因子下被剔除
即
C=I∗P C = I ∗ P
P已经确定,那么I不同,肯定对应不同的C
所以不同的合数只会被剔除一次
对于质数不存在 C=i∗P C = i ∗ P 的关系
所以肯定会被保留下来.
为什么i%prime[j]可以保证上述情况呢
将i 写成 i=pmin∗a i = p m i n ∗ a 的形式
若 i%prime[j] ==0;
则
pmin∗a∗prime[j+1] p m i n ∗ a ∗ p r i m e [ j + 1 ]
可以写成
a∗prime[j+1]∗pmin a ∗ p r i m e [ j + 1 ] ∗ p m i n
显然 pmin<prime[j+1] p m i n < p r i m e [ j + 1 ]
也就是刚才那个例子
12=3∗4=3∗(2∗2) 12 = 3 ∗ 4 = 3 ∗ ( 2 ∗ 2 )
总要化成
12=(3∗2)∗2=6∗2 12 = ( 3 ∗ 2 ) ∗ 2 = 6 ∗ 2 才对
参考:
https://www.jianshu.com/p/f16d318efe9b
http://blog.csdn.net/u014427196/article/details/44466461