C - 从特定的BIG RANGE获得素数

时间:2017-04-26 19:26:01

标签: c arrays memory

#include <stdio.h>
#include <math.h>
#define UPPER_LIMIT 2147483647
void sieve(unsigned long int n, unsigned long int primes[]);  
main()  
{  
    unsigned long int low, up, steps;  
    unsigned long int v[UPPER_LIMIT];  
    sieve(UPPER_LIMIT, v);  
    scanf("%ld\n",&steps);  
    for (unsigned long int i=0;i<steps;i++){  
        scanf("%ld %ld\n",&low,&up);  
        for(unsigned long int j=low; j<up; j++){  
            if (v[j] == 1){  
                printf("%ld\n",j);  
            }  
        }   
    }  
}  
void sieve(unsigned long int n, unsigned long int primes[])  
{  
    for (unsigned long int i=0;i<n;i++){  
        primes[i]=1;  
    }  
    primes[0]=0,primes[1]=0;   

    for (unsigned long int i=2;i<sqrt(n);i++) {  
        for (unsigned long int j=i*i;j<n;j+=i){  
            primes[j] = 0;  
        }  
    }  
}  

我正在尝试解决从特定范围打印素数的问题。 首先scanf我们会收到要审核的案例数量。范围由下一行stdin给出,例如(1 10)上限值可以是最大值2147483647.我正在使用Erastostenes筛选来查找素数。之后我想按升序排列printf素数。不幸的是我遇到了运行时错误,我认为这是因为我正在尝试创建非常大的数组。我需要就问题的可能解决方案提出建议。

stdin示例:

1  
1 10

stdout示例:

2  
3  
7  

3 个答案:

答案 0 :(得分:1)

使用unsigned long数组仅存储01毫无意义。

您只需要2147483647 / 8位来存储您需要的所有信息,因此您应该声明一个最多2147483647 / 8 + 1字节的数组:

const unsigned int SIZE = 1 + (2147483647 / 8);
unsigned char primes[SIZE];

甚至更好,通过堆分配:

const unsigned int SIZE = 1 + (2147483647 / 8);
unsigned char *primes = (unsigned char*)malloc(SIZE);

数组初始化变为:

for (unsigned i = 0; i < SIZE ; i++ ){  
    primes[i] = 1;
}

可以使用按位运算符>><<&来访问数组的各个位。实施这个是一个练习,因为这看起来像是一次大学练习。

答案 1 :(得分:0)

在全球范围内声明最大尺寸的素数数组 您可以使用向量来存储素数(c ++容器) 阵列大小最多可以是10 ^ 7到10 ^ 8, 你不能声明unsigned long int v[2147483647];这个大阵列 你也无法通过这种方法解决问题:)。

答案 2 :(得分:0)

您正在尝试创建一个局部变量,该变量在大多数实现中都存在于非常大的堆栈中。使用unsigned long类型的2G元素,您最有可能看到8 GB或16 GB。这对于筹码来说太大了。

将此变量创建为全局变量。这样它就不会存在于堆栈中,而是存在于(取决于实现)数据部分。

此外,由于此数组仅被赋值为0和1,因此将数组的类型更改为char,因此每个元素仅使用1个字节。这将为你节省大量的内存。