#include <iostream>
using namespace std;
void getPrime_1()
{
const int MAXN = 100;
bool flag[MAXN];
int primes[MAXN / 3 + 1], pi=0;
primes[pi++]=2; //2 是一个素数,先记录下来
int i, j;
for(i=0;i<MAXN;++i)flag[i]=false;//全部置假,没访问一个,相应位置真
for (i = 3; i < MAXN; i+=2){//大于2的偶数一定不是素数,所以只要判断奇数即可
if (!flag[i])//如果是素数
{
primes[pi++] = i;
for (j = i; j < MAXN; j += i)//i的倍数一定都不是素数
flag[j] = true;
}
}
for(i=0;i<pi;++i)
cout<<primes[i]<<" ";
cout<<endl;
}
这里使用了素数表,每一个bool型占用1个字节,共8位二进制位。而且这里除了多用了很多的无用bool变量在flag数组里,可以看到,我们使用的flag数组只用到2号位之后的所有奇数位。因此,这里可以进行压缩改进一下:
将flag数组减少一半
使用位操作符使空间占用减少为原来的八分之一
这里使用到对指定位置置1的操作:对于一个整数X可以通过将1左移n位后,与X进行或操作,使X的第n位置1。
int X=0;
int n=10;
X |= 1<< n; // 将 X 的第 n 位置 1
所以根据上面两条,优化后的代码如下:
void getPrime_2()
{
const int MAXN = 200;
const int BitN=(MAXN/2)/32+1;//
int flag[BitN];
int primes[MAXN / 3 + 1], pi=0;
primes[pi++]=2; //2 是一个素数,先记录下来
int i, j;
for(i=0;i<BitN;++i)flag[i]=0;//全置0,每访问过一个,相应位置1
for (i = 3; i < MAXN; i+=2){ //大于2的偶数一定不是素数,所以只要判断奇数即可
if (!((flag[(i/2) / 32] >> ((i/2) % 32)) & 1))
{
primes[pi++] = i;
//i的倍数一定都不是素数,其中,j加上一个i后为偶数,上一级已经不考虑了,所以还要加上一个i
for (j = i; j < MAXN; j =j+i+i)
flag[(j/2) / 32] |= (1 << ((j/2) % 32));
}
}
for(i=0;i<pi;++i)
cout<<primes[i]<<" ";
cout<<endl;
}
首先,根据最大数,判断需要32的整型多少个:
#include <iostream>
using namespace std;
void getPrime_1()
{
const int MAXN = 100;
bool flag[MAXN];
int primes[MAXN / 3 + 1], pi=0;
primes[pi++]=2; //2 是一个素数,先记录下来
int i, j;
for(i=0;i<MAXN;++i)flag[i]=false;//全部置假,没访问一个,相应位置真
for (i = 3; i < MAXN; i+=2){//大于2的偶数一定不是素数,所以只要判断奇数即可
if (!flag[i])//如果是素数
{
primes[pi++] = i;
for (j = i; j < MAXN; j += i)//i的倍数一定都不是素数
flag[j] = true;
}
}
for(i=0;i<pi;++i)
cout<<primes[i]<<" ";
cout<<endl;
}
这里使用了素数表,每一个bool型占用1个字节,共8位二进制位。而且这里除了多用了很多的无用bool变量在flag数组里,可以看到,我们使用的flag数组只用到2号位之后的所有奇数位。因此,这里可以进行压缩改进一下:
将flag数组减少一半
使用位操作符使空间占用减少为原来的八分之一
这里使用到对指定位置置1的操作:对于一个整数X可以通过将1左移n位后,与X进行或操作,使X的第n位置1。
int X=0;
int n=10;
X |= 1<< n; // 将 X 的第 n 位置 1
所以根据上面两条,优化后的代码如下:
void getPrime_2()
{
const int MAXN = 200;
const int BitN=(MAXN/2)/32+1;//
int flag[BitN];
int primes[MAXN / 3 + 1], pi=0;
primes[pi++]=2; //2 是一个素数,先记录下来
int i, j;
for(i=0;i<BitN;++i)flag[i]=0;//全置0,每访问过一个,相应位置1
for (i = 3; i < MAXN; i+=2){ //大于2的偶数一定不是素数,所以只要判断奇数即可
if (!((flag[(i/2) / 32] >> ((i/2) % 32)) & 1))
{
primes[pi++] = i;
//i的倍数一定都不是素数,其中,j加上一个i后为偶数,上一级已经不考虑了,所以还要加上一个i
for (j = i; j < MAXN; j =j+i+i)
flag[(j/2) / 32] |= (1 << ((j/2) % 32));
}
}
for(i=0;i<pi;++i)
cout<<primes[i]<<" ";
cout<<endl;
}
首先,根据最大数,判断需要32的整型多少个:
本文详细介绍了如何优化素数生成算法,并通过减少内存占用和位操作技巧实现空间节省。具体包括减少不必要的布尔变量使用,以及利用位操作符优化内存效率。通过实例演示了从原始算法到优化后的实现过程,旨在提高程序性能和资源利用率。
285

被折叠的 条评论
为什么被折叠?



