C 埃拉托斯烯筛

C 埃拉托斯烯筛,c,sieve-of-eratosthenes,sieve,C,Sieve Of Eratosthenes,Sieve,我在解决一个关于埃拉托什尼的问题时读到了埃拉托什尼的筛子。我相信你们知道我在说什么问题。 事情是这样的。我的代码能够正确显示100万以下的所有素数。 然而,当我尝试同样的实现为200万它给我一个分段错误。。。 我对错误产生的原因有一定的了解,但不知道如何纠正它。。。 这是一百万以下素数的代码 #include<stdio.h> int main(void) { int i,k=2; int j; int n=1000000; int prime[2000000

我在解决一个关于埃拉托什尼的问题时读到了埃拉托什尼的筛子。我相信你们知道我在说什么问题。 事情是这样的。我的代码能够正确显示100万以下的所有素数。 然而,当我尝试同样的实现为200万它给我一个分段错误。。。 我对错误产生的原因有一定的了解,但不知道如何纠正它。。。 这是一百万以下素数的代码

#include<stdio.h>
int main(void)
{
   int i,k=2;
   int j;
   int n=1000000;
   int prime[2000000]={};
   for(i=0;i<n;i++) // initializes the prime number array
   {
      prime[i]=i;
   }
   for(i=2;i<n;i++) // Implementation of the Sieve
   {
      if(prime[i]!=0)
      { 
         for(j=2;j<n;j++)
         {
            {
               prime[j*prime[i]]=0;
               if(prime[i]*j>n)
                  break;    
            }
         }
      }
   }
   for(i=0;i<n;i++) // Prints the prime numbers
      if(prime[i]!=0)
      {
         printf("%d\n"prime[i]);
      }
      return(0);
   }
}
#包括
内部主(空)
{
int i,k=2;
int j;
int n=1000000;
整数素数[2000000]={};

对于(i=0;i您正在堆栈中分配一个巨大的数组:

int prime[2000000]={};
4字节乘以200万等于8兆字节,这通常是最大堆栈大小。分配超过此值会导致分段错误

您应该在堆中分配数组,而不是:

int *prime;
prime = malloc(2000000 * sizeof(int));
if(!prime) {
    /* not enough memory */
}
/* ... use prime ... */
free(prime);

这是我的实现

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int* sieve(int n) {
  int* A = calloc(n, sizeof(int));
  for(int i = 2; i < (int) sqrt(n); i++) {
    if (!A[i]) {
      for (int j = i*i; j < n; j+=i) {
        A[j] = 1;
      }
    }
  }
  return A;
}
#包括
#包括
#包括
整数*筛子(整数n){
int*A=calloc(n,sizeof(int));
对于(int i=2;i<(int)sqrt(n);i++){
如果(!A[i]){
对于(int j=i*i;j
我在i5卡比湖上对其进行了首100000000个数字的基准测试

Here was my implementation (Java)
much simpler in that you really only need one array, just start for loops at 2.    

edit: @cheesehead 's solution was probably better, i just read the description of the sieve and thought it would be a good thought exercise.

      // set max;
      int max = 100000000;

      // logic
      boolean[] marked = new boolean[max]; // all start as false
      for (int k = 2; k < max;) {
         for (int g = k * 2; g < max; g += k) {
            marked[g] = true;
         }
         k++;
         while (k < max && marked[k]) {
            k++;
         }
      }

      //print
      for (int k = 2; k < max; k++) {
         if (!marked[k]) {
            System.out.println(k);
         }
      }

这是我的实现(Java)
更简单的是,实际上只需要一个数组,只需从2开始循环即可

编辑:@cheesehead的解决方案可能更好,我只是读了筛子的描述,认为这是一个很好的思考练习

void sieve(int n)
{
vector<bool> isPrime(n+1,true);
for(int i=2;i*i<=n;i++){
    if(isPrime[i])
    {
       for(int j=2*i;j<=n;j=j+i)
           isPrime[j]=false;
     }
  }
 for(int i=2;i<=n;i++){
    if(isPrime[i])
        cout<<i<<" ";
  }
}
//设置最大值;
int max=100000000;
//逻辑
boolean[]已标记=新的boolean[max];//所有开头均为false
对于(int k=2;k
简单实现埃拉托斯烯的筛选

方法: 我已经创建了一个大小为n+1的布尔向量(假设n=9,然后是0到9),它在所有位置都是真的。现在,对于I=2,将所有2的倍数标记为false(如n=9时为4,6和8)。对于I=3,将所有3的倍数标记为false(如n=9时为6和9).现在,对于i=4条件i*i9。那么,现在打印所有保留真值的位置

空隙筛(int n)
{
向量isPrime(n+1,真);

对于(int i=2;i*iDid您可以将
int n=1000000;
更改为
int n=2000000;
这看起来像是一个可能超出范围的数组访问:
prime[j*prime[i]]=0
。另外,您可能应该使用除
int
之外的其他数据类型。int不能保证为任何特定的大小,而不是16位。作为一个样式问题,我建议32k以上的数字使用
long
。如果他要索引一个大数组,他最好使用
size\u t
这个答案只是一个变量这是cheesehead和William Warner答案的重复。它没有回答关于分割错误的问题