Eratosthenes筛-C语言实现

时间:2018-10-24 13:08:02

标签: c for-loop sieve-of-eratosthenes sieve

我丢失了一些东西,但找不到。我还得到了一个input2.c文件,它具有print_prim函数,不允许我对其进行更改。

对于n = 10,它始终在打印

4, 5, 7, 9, 

我知道 print_prim 函数中有一个i + 2,但我无法解决。同样,我不允许更改print_prim函数。谁能看到我想念的东西吗?


  

main.c


#include <stdio.h>
#include <stdlib.h> 
#include "input2.h"

int main() {
    int n = lese_int();
    int laenge = n-1; 
    int *array;  
    array = malloc(sizeof(int) * laenge);  
    for (int i = 2; i <= n; i++) {
        array[i] = 1;  
    }

    for(int i=0;i<=n;i++) {
        if(array[i] == 1){
            for(int j = i ; i*j <= n ; j++){
                array[i*j] = 0;
            }   
        } 
    }
    print_prim(array, laenge);
    free(array); 
    return 0;
}
  

print_prim函数

void print_prim(int *array, int laenge) {
    for (int i=0; i<laenge; i++) {
        if (array[i] == 1) {
            printf("%d, ", i+2);
        }
    }
    printf("\n");
}

2 个答案:

答案 0 :(得分:2)

您需要的是移动2个元素的普通筛子。

int main() {
  int n;
  scanf("%d", &n);

  int *a = (int*)malloc(sizeof(int) * (n - 1));
  for (int i = 0; i < n - 1; i++ ) a[i] = 1;

  for (int i = 2; i*i <= n; i++) {
    if (a[i-2] == 1) {
      for (int j = i * i; j <= n; j+=i ) a[j-2] = 0;
    }
  }

  print_prim(a, n - 1);

  free(a);
  return 0;
}

说明:

  • 分配n-1元素以表示从2n(含)的数字。
  • 使用1初始化所有元素。为什么?因为查看print_prim,它会打印等于1的值。因此,我们所有的素数都需要移动2,并且其值应为1
  • 从2开始,我们将所有质数的倍数标记为0。保留1的是质数。有关详细信息,请参见https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
  • 由于print_prim被移动了2,因此我们需要传递n-1作为包容打印的第二个参数。

答案 1 :(得分:-1)

重新格式化代码

常见的帮助您格式化我们的步骤

#include <stdio.h>
#include <stdlib.h> 
#include "input2.h"

int main ( void )
{
  int n = lese_int();
  int laenge = n - 1; 
  int *array;

  array = malloc( sizeof( int ) * laenge );

  for ( int i = 2; i <= n; i++ )
  {
    array[i] = 1;
  }

  for ( int i = 0; i <= n; i++ )
  {
    if ( array[i] == 1 )
    {
      for ( int j = i; i * j <= n; j++ )
      {
        array[ i * j ] = 0;
      }
    }
  }

  for ( int i = 0; i < laenge; i++ )
  {
    printf( "%d, ", array[i] );
  }

  printf( "\n" );
  print_prim( array, laenge );
  free( array );
  return ( 0 );
}

print_prim函数是:

void print_prim ( int *array, int laenge )
{
  for ( int i = 0; i < laenge; i++ )
  {
    if ( array[i] == 1 )
    {
      printf( "%d, ", i + 2 );
    }
  }
  printf( "\n" );
}

注意:这种风格是个人风格,不打算像我这样使用空格或将括号向下弯曲来进行类似宗教的烈火。


阅读时发现错误:

您使用C99。在进行更改之前,请考虑到这一点。 (了解您的语言

您对n - 1个元素进行了内存分配,但是您尝试从元素2到元素n进行访问,这两个过程都包含在第一个for循环中。 (了解内存分配的工作原理

数组从零开始插入笑话),因此,您无法到达元素n或元素n - 1。< / p>

print_prim仅打印包含1的数组元素的值加2。 换句话说:尝试找到包含1的数组中的所有位置,并以2递增该位置。(了解如何进行调试-


我建议您研究这种语言的工作原理,而不要研究基于 trial'n'error 的编程。这样可以节省大量时间,并且您会学到更多。