#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
答案 0 :(得分:1)
使用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;
}
可以使用按位运算符>>
,<<
和&
来访问数组的各个位。实施这个是一个练习,因为这看起来像是一次大学练习。
答案 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个字节。这将为你节省大量的内存。