1.先将所有数设置为素数
2.依次遍历,遇到素数,就将其所有倍数设置为合数,即Isprime[i]=true
ps:这里不会出现遗漏或者误判的情况
如:当前判断n是否为素数,按照暴力的求法,我们已经判断了2~n-1中的数,
即已经将2~n-1中的素数全部找出来了,如果n为合数,那么它必有一个因子属于
2~n-1中,而我们之前就已经将2~n-1中为素数的倍数全部设为合数,所有这里不会
错判或漏判
原版
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 100; //求100以内素数的个数
int cnt = 0; //计数
bool Isprime[n]; //false为素数,true为合数 ,这里系统默认将每个值设置为false
for(int i = 2; i <= n ; i++){
if(!Isprime[i]){
cnt++;
for(int j = 2 * i; j <= n; j += i){
Isprime[j] = true; // 将当前素数的倍数全部改为合数
}
}
}
cout << cnt << endl;
return 0;
}
优化版
优化版本就是将第二个for循环中的j=2*i改成了i*i,这样可以减少计算的次数
ps: 当i=2时 ,我们就计算了 2*2,2*3,2*4 ......
当i=3时,我们就计算了 3*2,3*3,3*4.......
这里容易发现 3*2 和 2*3 是等价的,所以当计算到 i 时,只需从 i*i 开始计算
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n = 100; //求100以内素数的个数
int cnt = 0; //计数
bool Isprime[n]; //false为素数,true为合数 ,这里系统默认将设置为false
for(int i = 2; i <= n ; i++){
if(!Isprime[i]){
cnt++;
for(int j = i * i; j <= n; j += i){
Isprime[j] = true; // 将当前素数的倍数全部改为合数
}
}
}
cout << cnt << endl;
return 0;
}