#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;
        }
    }
}


我正在尝试解决从特定范围打印素数的问题。
首先,我们得到要审查的案件数。该范围由stdin的下一行给出,例如(1 10)的最大值可以最大为2147483647。之后,我想按升序scanf质数。不幸的是,我遇到了运行时错误,并且我认为这是因为我要创建的数组很大。我需要有关可能解决问题的建议。

stdin的示例:

1
1 10


标准输出示例:

2
3
7

最佳答案

使用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;
}


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

10-08 14:32