#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
数组仅存储0
或1
没有意义。
您只需要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;
}
可以使用按位运算符
>>
,<<
和&
对数组的各个位进行访问。实施这项工作是一项练习,因为这看起来像是大学练习。