埃拉托色尼筛选法
简介
针对自然数列中的自然数而实施的,用于求一定范围内的质数。
算法思想
- 挖去1;
- 用刚才被挖去的数的下一个数p,把p的倍数挖掉;
- 检查p是否小于sprt(n)的整数部分,如果是,则返回(2)继续执行,否则就结束;
- 纸上剩下的数就是素数。
代码
递归实现
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* Get_Prime(int num)
{
int *a = NULL, *get = NULL;
int *p = NULL, *q = NULL;
int i = 0, j = 0;
/*
* the exit.
*/
if (num <= 10)
{
a = malloc (sizeof(int) * 10);
for (i = 0; i < 10; i++)
a[i] = 0;
a[2-1] = 2; a[3-1] = 3;
a[5-1] = 5; a[7-1] = 7;
a[num - 1] = -1;
return a;
}
/*
* step 1: get the prime under sqrt(num)
*/
get = Get_Prime ((int)( sqrt ((double)num) + 0.5 ));
/*
* step 2: malloc the space of 1 - num.
*/
a = malloc (sizeof(int) * (num));
/*
* step 3: init the space.
* The end is -1 as a sign.And take out number 1;
*/
for (i = 0; i < num; i++)
a[i] = i + 1;
a[num - 1] = -1; a[0] = 0;
/*
* step 4: take out the number n*(*p)
*/
for (p = get; (*p) != -1; p++)
{
if (*p == 0)
continue;
for (j = 2; (*p) * j < num; j++)
a[ (*p) * j - 1] = 0;//printf("take out%d, in %d,at %d\n",(*p)*j,*p,num);
}
/*
* step 5:return and free
*/
free (get);
return a;
}
int main()
{
int num;
int *a = NULL;
int i;
scanf ("%d", &num);
if (num <= 0)
return 0;
a = Get_Prime (num);
for (i = 0; a[i] != -1; i++)
if (a[i])
printf ("%d ", a[i]);
putchar('\n');
return 0;
}
循环实现
#include "stdio.h"
#include "math.h"
int isPrime(int n)
{
int sqt = sqrt((double)n);
int i;
for(i = 2; i <= sqt; i++ )
{
if(n%i==0) return 0;
}
return 1;
}
void GetPrime_Erato(int *n)
{
int *num = NULL, *num_sqrt = NULL;
int *q = NULL, i = 0, *p = NULL;
int sqr = (int)sqrt((double)*n);
//¥¥Ω®ƒ⁄¥Êø’º‰
num = (int *) malloc(sizeof(int)*(*n));
if(!num)
{
printf("ƒ⁄¥Ê≤ª◊„£°");
exit(1);
}
num_sqrt = (int *) malloc(sqr * sizeof(int)) ;
if(!num_sqrt)
{
printf("ƒ⁄¥Ê≤ª◊„£°");
exit(1);
}
//ƒ⁄¥Êø’º‰≥ı ºªØ
for(i = 0; i < (*n); i++)
num[i] = i + 1;
for(i = 0; i < sqr; i++)
num_sqrt[i] = i + 1;
//‘≠ º ‰≥ˆ
printf("\n");
printf("%d“ªœ¬µƒ ˝”–:", *n);
for(q = num; q < &num[(int)(*n)] ; q++)
{
if(*q != 1)
printf("%d\t", *q);
}
printf("\n");
printf("\n");
//…æ≥˝
for(q = &num_sqrt[1]; q < &num_sqrt[sqr]; q++)
{
if(isPrime(*q))
{
for(i = *q + 1; i <= *n; i++)
{
if(i % *q == 0)
num[i-1] = 1;
}
printf("…æ≥˝ %d µƒ±∂ ˝∫Û:", *q);
for(p = num; p < &num[*n] ; p++)
{
if(*p != 1)
printf("%d\t", *p);
}
printf("\n");
}
}
// ‰≥ˆ
printf("\n");
printf("%d“ªœ¬µƒÀÿ ˝”–:", *n);
for(q = num; q < &num[(int)(*n)] ; q++)
{
if(*q != 1)
printf("%d\t", *q);
}
}
int main()
{
int n = 100;
GetPrime_Erato(&n);
return 0;
}
说明
递归实现的编写时间是2017年,循环实现是在2015年,其中由于平台的原因,中文字体在Mac上是无法识别的所以产生了乱码。