我想得到2和pow(2,32)之间的所有素数,但是,因为pow(2,32)很大,我不能声明那个大数组。以下是我的代码
struct prims_n
{
long long *prim;
long long size;
};
struct prims_n get_prim_number(long long number)
{
long long count = 0;
struct prims_n result;
bool* a = new bool[number+1];
memset(a, 1, number+1);
for(long long i = 2; i <= sqrt(number); i ++)
{
if(a[i])
{
for(long long j = 2; j <= number/i; j ++)
{
a[i*j] = 0;
}
}
}
for (long long i = 2; i <= number; i++)
{
if (a[i]) count ++;
}
result.size = count;
long long k = 0;
result.prim = new long long[count];
for (long long i = 2; i <= number; i++)
{
if (a[i] && k < count)
{
result.prim[k] = i;
k ++;
}
}
return result;
}
int main(int argc, char* argv[])
{
struct prims_n result = get_prim_number(pow(2, 26));
cout << "prim numbers:" << result.size
<< " pow(2, 32)=" << pow(2, 32) << endl;
return 0;
}
我的操作系统为Windows
,IDE为Visual Studio 2012
数字pow(2,32)太大而Sieve of Eratosthenes
的计算效率不高。那么,我该怎么办?
答案 0 :(得分:4)
简单方法:构建64位目标并安装大量RAM。
或者你可以通过不为每个数字存储一个int而只减少一点来减少所需的内存。 std::vector<bool>
或std::bitset<N>
将是很好用的容器。 bitset
要求在编译时知道大小,vector
允许它更改。 BTW,vector<bool>
专门用于优化内存使用。
当然你并不需要存储所有数字1..N,因为你知道偶数不能是素数。所以你可以使用一个数组,例如索引i
的元素代表2*i+1
是素数时的信息。
其他选项:只存储素数,然后对每个要测试的新数字进行测试,尝试将其除以已计算和存储的素数(不是全部,最多只能达到sqrt())。
或者使用窗口视图进入筛网:将已知的素数存储在一个容器中,并为完整缓冲区的一部分分配空间。如果您已完成缓冲区,请转到下一个窗口。
答案 1 :(得分:-2)
素数在表格(6K + 1)或(6K - 1)上, 循环k并检查6K + 1或6K-1是否不能被2,3,5,7整除为