还是之前的问题,求出MAXSIZE以内的所以质数
下面我们看下原理
所有的合数都可以分解为两个数的乘积,那么我们建立一个isPrime[MAXSIZE+1]的表,先把所有的元素设置成默认为是质数,true,设置两重循环,将i*j处的值设置成false,这样最后得到的是true元素对应的角标就是质数了,下面附上代码:
#include #include
using namespacestd;#define max 99999
int prime[max+1];bool isPrime[max+1];int count = 0;intmain()
{for (int i = 0;i <= max;i++)
{
prime[i]= 0;
isPrime[i]= true;
}
clock_t start,end;//用于计时
start =clock() ;for (int i = 2;i <= max;i++)
{for(int j = 2;j <= max && i*j <= max;j++)
{
isPrime[i*j] = false;
}
}
end=clock();for(int i = 2;i <= max;i++)
{if(isPrime[i])
{
cout<
}
}
cout<
}
这里我们可以看到,其实没有经过什么优化,让我们看戏程序的效率:
这个效率已经很高很高了,比之前的筛选法还要高了,下面我们看下在这个算法中还能怎么样去减少循环次数,减小程序的时间复杂度
设想下,在2*4 = 8处和4*2 = 8处,或者 2* 12 = 24和3*8 = 24处,都分别进行了多次赋值,这样看来,效率有所降低,下面是我们优化过的代码,
#include #include
using namespacestd;#define max 99999
int prime[max+1];bool isPrime[max+1];int count = 0;intmain()
{//将数组初始化
for (int i = 0;i <= max;i++)
{
prime[i]= 0;
isPrime[i]= true;
}
clock_t start,end;//用于计时
start =clock() ;for (int i = 2;i <= max;i++)
{if(isPrime[i])
{
prime[count++] =i;
}for(int j = 0;j < count && i*prime[j] <= max;j++)
{
isPrime[i*prime[j]] = false;if (i % prime[j] == 0)
{break;
}
}
}
end=clock();for(int i = 2;i <= max;i++)
{if(isPrime[i])
{
cout<
}
}
cout<
}
优化过的代码
通过prime数组保存已经得到的质数,然后用这些质数去乘以i得到合数,并将该合数对应的位置置为false,关键还有一个
if (i % prime[j] == 0)
{break;
}
操作,比如,当i为8的时候,搜索到2,也就是2*8 = 16,处置为false就可以了,跳出J的循环,因为假如到8*3=24的话 24 = 2*12,可以由一个更大的合数得到,这样就可以减少循环次数,优化时间复杂度,下面看程序运行结果:
这个时间,你懂的!