#include<iostream>
#define PrimeNum 100
using namespace std;
bool IFprime[(int)1e6] = { 0 };
int prime[(int)1e6] = { 0 };
void get_prime(void) {
int cnt = 0;
for (int i = 2; i <= PrimeNum; i++) {
if (!IFprime[i])prime[cnt++] = i;
for (int j = 0; j < cnt; j++) {
IFprime[i * prime[j]] = 1;
if (i % prime[j] == 0)break;
}
}
}
int main(void) {
get_prime();
for (int i = 0; i < 100; i++)cout << prime[i]<<endl;
}
1.假定我们要筛掉的合数为x,因为每次都用最小质因子去筛选,那么x/prime[j] >= prime[j] , 也就保证了在遍历到i==x/prime[j]之前,prime[j]这个最小质因子已经存在于prime数组中,也就保证了不会出现以下情况:
我们想要筛掉x , x为i*prime[j] , 而遍历到i时,这个prime[j]还没有存进数组的情况.
2.为什么能保证每次筛的合数x都是i*x的最小质因子
因为prime[j]是从小到大枚举的
故i % prime[j] == 0 时, prime[j]为它的最小质因子,prime[j] * i 的最小质因子也是prime[j]
i%prime[j] != 0时, prime[j] 小于 i的最小质因子,prime[j]*i的最小质因子仍是prime[j]
又或者说i % prime[j] == 0 , i的最小质因子为prime[j] , 如果它不break,i*prime[j+1]筛除的数字也包含了因子i,因子i又可以拆分为prime[j] *其它因子,prime[j+1] > prime[j] , 故此时i*prime[j+1]最小质因子仍然是prime[j]。
证毕。
所以每个合数只会被筛一次,时间复杂度故为O(N).
里层循环j<cnt判断条件是多余的
为什么不需要写j<cnt
- primes数组中存有<=i的所有质数
- 当i是合数时, prime[j]为i的最小质因子时break, j不会越界
- 当i是质数时, prime数组的最后一个元素就是i, 当pj==i时, break,依然不越界