目的:求N以内的所有质数
算法:英文名忘了,中文名是筛选法
原理:是从小到大把所有的质数的倍数剔除出去,直到N的开方为止
技巧:
1,很显然,当计算3的倍数时应该从9开始算起,也就是说计算任何一个质数的倍数时都从平方和算起
2,先把2的倍数算出来,这样以后再算其他质数P的倍数时,可以从平方和起一次加2*P,因为P是质数,所以是奇数,所以P*P+P是偶数,所以合理的大于P*P的下一个P的倍数是P*P+2*P,同理,以后依此加2*P
代码:
#include <conio.h>
#include <vector>
#include<iostream>
#include<iomanip>
using namespace std;
//---------------------------------------------------------------------------
void __fastcall FindPrimes(const unsigned int& num,vector<unsigned int>& vec)
{
bool *numbers=new bool[num+1];
numbers[2]=true;//true为质数
for(unsigned int i=3;i<=num;i++)
numbers[i]=i%2;
unsigned int ininum=3;
unsigned int t;
while((t=ininum*ininum)<=num)
{
while(t<=num)//寻找倍数
{
numbers[t]=false;
t+=ininum<<1;//乘2
}
while(!numbers[++ininum]);//寻找下一个质数
}
for(unsigned int i=2;i<=num;i++)
{
if(numbers[i])
vec.push_back(i);
}
delete[] numbers;
}
//----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
vector<unsigned int> primes;
FindPrimes(1000,primes);
vector<unsigned int>::iterator vi=primes.begin();
int format=0;
for(;vi!=primes.end();vi++)
{
cout<<setw(4)<<*vi<<" ";
format++;
if(format%16==0)
{
cout<<endl;
format=0;
}
}
cout<<"找到质数"<<primes.size()<<"个"<<endl;
getchar();
return 0;
}
简单介绍一下厄拉多塞筛法。厄拉多塞是一位古希腊数学家,他在寻找素数时,采用了一种与众不同的方法:先将2-N的各数写在纸上:
在2的上面画一个圆圈,然后划去2的其他倍数;第一个既未画圈又没有被划去的数是3,将它画圈,再划去3的其他倍数;现在既未画圈又没有被划去的第一个数 是5,将它画圈,并划去5的其他倍数……依次类推,一直到所有小于或等于N的各数都画了圈或划去为止。这时,表中画了圈的以及未划去的那些数正好就是小于 N的素数。
这很像一面筛子,把满足条件的数留下来,把不满足条件的数筛掉。由于这种方法是厄拉多塞首先发明的,所以,后人就把这种方法称作厄拉多塞筛法。
在计算机中,筛法可以用给数组单元置零的方法来实现。具体来说就是:首先开一个数组:a[i],i=1,2,3,…,同时,令所有的数组元素都等于下标 值,即a[i]=i,当i不是素数时,令a[i]=0 。当输出结果时,只要判断a[i]是否等于零即可,如果a[i]=0,则令i=i+1,检查下一个a[i]。
筛法是计算机程序设计中常用的算法之一。