用“埃氏篩法”求2~100以內的素數。
用“埃氏篩法”求2~100以內的素數。2~100以內的數,先去掉2的倍數,再去掉3的倍數,再去掉5的倍數,……依此類推,最後剩下的就是素數。
請上傳壓縮後的原始碼檔案,程式碼可直接並正確執行;
請注意程式碼風格:類名、變數名的命名,以及必要註釋等等;
以防上傳失敗,請同時把程式碼貼到文字框中。
埃氏篩法定義:埃拉託斯特尼篩法,簡稱埃氏篩或愛氏篩,是一種由希臘數學家埃拉託斯特尼所提出的一種簡單檢定素數的演算法。要得到自然數n以內的全部素數,必須把不大於根號n的所有素數的倍數剔除,剩下的就是素數。
步驟舉例
詳細列出演算法如下:
-
列出2以後的所有序列:
-
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
-
-
標出序列中的第一個素數,也就是2,序列變成:
-
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
-
-
將剩下序列中,劃掉2的倍數,序列變成:
-
2 3 5 7 9 11 13 15 17 19 21 23 25
-
-
如果現在這個序列中最大數小於最後一個標出的素數的平方,那麼剩下的序列中所有的數都是素數,否則回到第二步。
-
本例中,因為25大於2的平方,我們返回第二步:
-
剩下的序列中第一個素數是3,將主序列中3的倍數劃掉,主序列變成:
-
2 3 5 7 11 13 17 19 23 25
-
-
我們得到的素數有:2,3
-
25仍然大於3的平方,所以我們還要返回第二步:
-
現在序列中第一個素數是5,同樣將序列中5的倍數劃掉,主序列成了:
-
2 3 5 7 11 13 17 19 23
-
-
我們得到的素數有:2,3,5 。
-
因為23小於5的平方,跳出迴圈.
結論:2到25之間的素數是:2 3 5 7 11 13 17 19 23。
題目實現
package 埃氏篩法求素數;
public class Main {
public static void main(String[] args) {
int aa[]=new int [101];
aa[0] = aa[1] = 1;
aa[2]=0;
int k=2,tt=0;
while(tt<101)
{
for(int i=1; i<aa.length; i++) //將不是素數的數篩出
{
if(i%k==0&&i!=k)
aa[i]=1;//不符合要求的全部置為1
}
for(int i=1; i<aa.length; i++) //將篩選後的第一個數當做新的篩子
{
if(i>k&&aa[i]==0)
{
k=i;
break;
}
}
tt++;
}
for(int i=1; i<aa.length; i++)
if(aa[i]==0) System.out.printf("%d ",i);
}
}
還有一種方法也可以
/*需求:用埃氏篩法求解100(擴充套件到n)以內的素數;
*思路:
*1. 設定一個邊界(由使用者輸入),用以求1到它之內的素數;
*2. 明確素數、埃氏篩法的概念;
*3. 需要用到陣列來儲存素數的標記;
*4. 埃氏篩法中,只需要從這個數的當前倍數判斷即可,如5的5倍、5的6倍,因為5的2、3、4倍已經分別在2、3、4的5倍體現;
*5. 每行輸出10個素數,並求出總個數;
*步驟:
*1. 引入Scanner,並引導使用者輸入一個正整數n來當做邊界;
*2. 如果資料不能被所有2到n的平方根整除,那麼這個數就是一個素數;(埃氏篩法核心思想1);
*3. 預設給定區間除0、1外全部為素數,引入int i、j,在區間內(即應不大於給定的n)從j的j倍開始遍歷,如果有數值不滿足素數條件則判為true,即實現了對全部資料的標記;(埃氏篩法核心思想2);
*4. 用一個布林陣列來儲存標記(true、false),並計算true的個數;
*5. 設計輸出語句,囊括區間、素數個數,並做到每行列印10個素數。
*/
import java.util.*;
public class Week3Homework
{
public static void main(String[] args)
{
System.out.println("請輸入一個正整數用以求解0到它的素數:");
Scanner intnum = new Scanner(System.in);
int n = intnum.nextInt();
isPrime(n);//呼叫isPrime函式
}
public static void isPrime(int num)//定義isPrime,對資料做標記
{
boolean[] mark = new boolean[num+1];//因為角標從0開始,為了對應,資料從0開始,所以長度為num+1
mark[0] = false;//0不是素數
mark[1] = false;//1不是素數
for(int i = 2; i <= num; i++)
{
mark[i] = true;//初始化:假定2到num都是素數,均標識為true
}
for(int i = 2; i <= Math.sqrt(num);i++)//埃氏篩法核心思想的體現
{
if(mark[i] == true)
{
for(int j = i;j*i<=num;j++)//更換標記,剔除非素數
{
mark[j*i] = false;//i的倍數全部置為false
}
}
}
int count = 0;
System.out.println("0到"+num+"的素數是:");
for(int i = 2; i<=num; i++)//對布林陣列進行遍歷,計算true標記的個數(即素數的個數)
{
if(mark[i] == true)
{
count++;
System.out.print(i+"\t");//"\t"是橫向製表符
if(count%10 == 0)//一行輸出10個數據後,換行
{
System.out.println();
}
}
}
System.out.println("\n0到"+num+"中的素數一共有"+count+"個。");
}
}