埃拉托色尼筛选法

埃拉托色尼筛选法

简介

针对自然数列中的自然数而实施的,用于求一定范围内的质数。

算法思想

  • 挖去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上是无法识别的所以产生了乱码。

猜你喜欢

转载自blog.csdn.net/guoxuan_chn/article/details/78163524
今日推荐