一、題目
題目描述:
給你一個正整數N,在[2,N]這個區間內有多少個素數。
輸入描述:
先輸入一個整數T,代表有T(1<=T<=100000000)組數據,然后有T行正數N(1<N<=10000000).
輸出描述
對於每一個N,輸出在這[2,N]區間內,有多少個素數。
二、暴力素數篩
整體實現思想:兩層循環,遍歷每一個數,判斷其是否為素數。
代碼如下:
1 //暴力素數篩
2 vector<int> Find_Prime_number1(int n) 3 { 4 vector<int> ans; 5
6 //從2開始,1不是素數
7 for (int i = 2; i <= n; i++) 8 { 9 //默認是素數
10 int flag = 1; 11 //判斷i是否是素數
12 for (int j = 2; j < i; j++) 13 { 14 if (i % j == 0) 15 { 16 flag = 0; 17 break; 18 } 19 } 20 if (flag) 21 ans.push_back(i); 22 } 23
24 return ans; 25 }
對其進行簡單的優化,第二層的結束條件可以優化為sqrt(i),因為右面的所有數字都在面被遍歷過。
代碼如下:
1 //暴力素數篩優化
2 vector<int> Find_Prime_number2(int n) 3 { 4 vector<int> ans; 5
6 //從2開始,1不是素數
7 for (int i = 2; i <= n; i++) 8 { 9 //默認是素數
10 int flag = 1; 11 //優化循環結束調節,開方
12 for (int j = 2; j <= sqrt(i); j++) 13 { 14 if (i % j == 0) 15 { 16 flag = 0; 17 break; 18 } 19 } 20 if (flag) 21 ans.push_back(i); 22 } 23
24 return ans; 25 }
三、朴素素數篩(埃拉托斯特尼篩法)
整體實現思想:遍歷到的每一個素數,將其的倍數設置為合數,避免對每一樹的判斷,可以大幅度節省時間,但是注意第二層循環的開始條件,從而i*i開始,而不是i*2。時間復雜度為O(n*loglogn)。
代碼如下:
1 //朴素素數篩(埃拉托斯特尼篩法),時間復雜度為O(n * loglogn)
2 vector<int> Find_Prime_number3(int n) 3 { 4 vector<int> ans; 5
6 vector<bool> flag(n + 1, true); 7
8 //0和1不是素數,直接初始化好
9 flag[0] = 0; 10 flag[1] = 0; 11
12 //從2開始,1不是素數
13 for (int i = 2; i <= n; i++) 14 { 15 //如果當前數字是素數
16 if (flag[i]) 17 { 18 //i的倍數標記被不是素數
19 for (int j = i * i; j <= n; j += i) 20 { 21 flag[j] = false; 22 } 23 ans.push_back(i); 24 } 25 } 26
27 return ans; 28 }
四、線性素數篩(歐拉篩法)
整體實現思想:在朴素素數篩的過程中我們會重復篩到同一個數,例如12同時被2和3篩到,30同時被2、3和5篩到。所以我們引入歐拉篩,也叫線性篩,可以在 時間內完成對2~n的篩選。它的核心思想是:讓每一個合數被其最小質因數篩到。
代碼如下:
1 //線性素數篩(歐拉篩法),時間復雜度為O(n)
2 vector<int> Find_Prime_number4(int n) 3 { 4 vector<int> ans; 5
6 vector<bool> flag(n + 1, true); 7
8 //0和1不是素數,直接初始化好
9 flag[0] = 0; 10 flag[1] = 0; 11
12 //從2開始,1不是素數
13 for (int i = 2; i <= n; i++) 14 { 15 //如果當前數字是素數
16 if (flag[i]) 17 ans.push_back(i); 18
19 //顯示標記合數
20 for (int j = 1; j <= ans.size() && i * ans[j-1] <= n; j++) 21 { 22 flag[i*ans[j - 1]] = false; 23 if (i % ans[j - 1] == 0) 24 break; 25 } 26 } 27
28 return ans; 29 }
五、參考文章
https://blog.csdn.net/qq_42685893/article/details/86761727
https://zhuanlan.zhihu.com/p/100051075#