【发布时间】:2019-11-21 07:03:22
【问题描述】:
我正在使用这个程序来检查一个数字是否是素数。
使用算法 - 筛子:
#include<bits/stdc++.h>
//#define _max 2000000001
#define _max 20000001
using namespace std;
bool sieve[_max];
void init()
{
memset(sieve,true,sizeof(sieve));
sieve[0]=sieve[1]=false;
for(int i=2;i<_max;i+=2)
{
sieve[i]=false;
}
}
void go_sieve(int n)
{
n++;
for(int i=3;i<n;i+=2)
{
if(sieve[i]==false)
continue;
for(int j=2*i;j<n;j+=i)
sieve[j]=false;
}
}
void print(int n)
{
n++;
printf("-------------\n");
for(int i=0;i<n;i++)
{
if(sieve[i])
cout << i << " ";
}
printf("\n-------------\n");
}
int main()
{
init();
int n;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
go_sieve(x);
//print(x);
if(sieve[x])
printf("Prime\n");
else
printf("Not prime\n");
}
return 0;
}
现在它可以运行到 2e7 并且非常顺利,但是我想检查到 2e9,如果我将我的 _max 更改为 2000000001 它会给我 segmentation error 并以错误代码退出。
我该如何解决这个问题?
我尝试了一种新的 set 方法:
#include<bits/stdc++.h>
//#define _max 200001
//#define _max 20000001
#define _max 2000000001
using namespace std;
set<int>prime;
set<int>nprime;
void init()
{
prime.insert(2);
}
void go_sieve()
{
for(int i=3;i<_max;i+=2)
{
if(prime.find(i)==prime.end() && nprime.find(i)==nprime.end())
{
prime.insert(i);
//cout << i << endl;
for(int j=2*i;j<_max;j+=i)
nprime.insert(j);
}
if(nprime.find(i)!=nprime.end())
nprime.erase(nprime.find(i));
}
}
void print()
{
set<int> ::iterator itt;
printf("-------------\n");
for(itt=prime.begin();itt!=prime.end();itt++)
{
cout << *itt << " ";
}
printf("\n-------------\n");
}
int main()
{
init();
go_sieve();
//print();
int n;
scanf("%d",&n);
while(n--)
{
int x;
scanf("%d",&x);
if(prime.find(x)!=prime.end())
printf("Prime\n");
else
printf("Not prime\n");
}
return 0;
}
目标是在 512MB~1GB 内存内执行。
【问题讨论】:
-
程序对数组使用了大量内存(大概8G)。也许你的系统无法处理。你有多少内存?是否允许过度提交?
-
有些系统对静态分配的大小有限制,您是否尝试过使用 std::vector 而不是数组?您还应该确保编译为 64 位,否则您将被限制为最多 4gb 的内存
-
鉴于
#include<bits/stdc++.h>的可怕用途,他必须使用 gcc,所以 bool 可能是 1 个字节 -
大多数 C++ 运行时库提供 std::vector
的专门实现,每个元素仅使用 1 位。
标签: c++ segmentation-fault primes sieve-of-eratosthenes