首先,最笨的方法,考虑不能被所有小于它素数除尽的数就是素数:
int countPrimes(int n) { vector<int> a; a.push_back(2); if(n<3) return 0; int count=1; int i,j; for(i=3;i<n;i=i+2) { for( j=0;j<a.size();j++) { if(i%a[j]==0&&i/a[j]>1) break; } if(j==a.size()) { cout<<i<<endl; count++; a.push_back(i); } } return count; }
这么low,肯定时间复杂度太高,每次都要都所有素数检查一次
改进一下,使用高级的埃拉托斯特尼筛法(好难拼呀),如果一个数是另一个数的倍数,那这个数肯定不是素数,所以从2 开始将所有素数的倍数都标注为非素数
vector<bool> p(n,true); for(int i=2;i<n;i++) { if(p[i]) { for(int j=i*2;j<n;j=j+i) { p[j]=false; } } } int count=0; for(int i=2;i<n;i++) if(p[i]) count++; return count;
(但是,2的倍数是非素数,我们可以直接不考虑2的倍数), 从3开始,将6,,9,12,15.。。。标为非素数一直到N。】
if(n<=2) return 0; vector <bool> l(n,true); int sum=1; // int upper=sqrt(n); for(int i=3;i<n;i+=2) { if(l[i]) { sum++; // if(i>upper) continue; for(int j=i*i;j<n;j=j+i) { l[j]=false; } } } return sum;
但是i*i可能值很大,大于int型的返回,所以要对i加一个限制或从j=i+i开始
if(n<=2) return 0; vector <bool> l(n,true); int sum=1; int upper=sqrt(n); for(int i=3;i<n;i+=2) { if(l[i]) { sum++; if(i>upper) continue; for(int j=i*i;j<n;j=j+i) { l[j]=false; } } } return sum;