題目描述
令Pi表示第i個素數≈酰現任給兩個正整數M <= N <= 10000如叼,請輸出PM到PN的所有素數四啰。
輸入描述:
輸入在一行中給出M和N宁玫,其間以空格分隔。
輸出描述:
輸出從PM到PN的所有素數柑晒,每10個數字占1行欧瘪,其間以空格分隔,但行末不得有多余空格匙赞。
輸入例子:
5 27
輸出例子:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
思路和知識點:
- 素數:在大于1的整數中佛掖,只能被1和這個數本身整除的數妖碉,如2、3芥被、5欧宜、7、11拴魄。也叫質數冗茸。(1不是素數)
- Math.sqrt(): JAVA中實現求一個數的平方根
- 如何判斷一個數是否是素數?
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sann = new Scanner(System.in);
int left = sann.nextInt();
int right = sann.nextInt();
int times = 0;//用來計數
for(int i=1; ;i++){ //從1開始判斷每個數是否是素數
if(isPrime(i)==true){
times++;//如果是素數,計數加一
if(times<right && times>=left){ //如果在要求的范圍內匹中,則要十個一行輸出
if((times-left+1)%10 == 0 ){
System.out.print(i);
System.out.print("\n");//輸出該數并換行
}else{
System.out.printf("%d ",i);//輸出該數并空格
}
}
if(times == right){
System.out.printf("%d",i);
break; //跳出for循環(huán)
}
}//end if
}//end for;
}
// // 判斷一個數是否是素數的方法
public static boolean isPrime(int num){
boolean flag = true;
if(num==1){
flag = false;
}
if((num == 2 || num ==3)&& num!=1){
flag = true;
}else{
for(int i=2;i<=Math.sqrt(num);i++ ){
if(num%i==0){
flag = false;
break;
}
}
}
return flag;
}
}
哈哈哈哈哈哈夏漱,這道題實在折磨了我太長時間,網上找不到能編譯成功的算法顶捷,自己小白一個挂绰,從判斷素數的方法一句一句寫起來,中間各種報錯服赎,還是使用java不熟練葵蒂,很多語句都不太會寫,連數組的初始化都要百度ORZ··· 好在重虑,經過艱苦卓絕的頑強掙扎践付,終于把這道題解決了,相信以后寫算法的能力也能有所提升缺厉,畢竟這是嚴格意義上自己第一道獨立解決的算法題荔仁。
在此感謝LeetCode平臺,提供了算法在線編譯調試的平臺芽死,讓我能一步步的嘗試運行,從而找到自己原始版本中的錯誤次洼。
總結一下关贵,這道題做不出來的主要錯誤在于邏輯錯誤,好幾個地方都是我的if語句的邏輯沒有弄明白卖毁,幾個if語句之間相互并列反而沒有了需要的效果揖曾。
再次,向掙扎在算法路上的自己致敬亥啦!要繼續(xù)勇敢的不放棄的走下去炭剪!
補充(以下僅是思路,沒有成功實現翔脱,可以不看奴拦,特此提醒):
在掙扎這道題的過程中,有看到關于素數判斷的一些相關理論届吁,包括孿生素數错妖,還有“素數都在六的倍數兩側绿鸣,但六的倍數兩側不一定都是素數≡萋龋”作為一個嚴謹又充滿好奇心的喵嗚潮模,我嘗試了一下以六為倍數增加的方法,第一次寫出來后在35這個數字這里卡住了痴施,因為35的開平方是5擎厢,而我的for循環(huán)從7開始,所以35這個數字沒有進入for循環(huán)進行判斷辣吃,調整后將判斷素數函數寫作如下:
// // 判斷一個數是否是素數的方法
public static boolean isPrime(int num){
boolean flag = true;
if(num==1){
flag =false;
}
if((num == 2 || num ==3)&& num!=1){
flag =true;
}else{
if(num%6 != 1 && num%6!=5){
flag = false;
} else{
if(num<49){ //小于7的平方的話动遭,就不開平了
for(int i = 7;i<num-5;i+=6){
if(num%i == 0){
flag = false;
break;
}
}
}else{
for(int i = 7;i<=Math.sqrt(num);i+=6){
if(num%i == 0){
flag = false;
break;
}
}
}//end else
}//end else
}//end else
return flag;
}// end isPrime
在調試運行后,又發(fā)現25不是素數齿尽,但是根據我們的算法得到的是素數沽损,跟著邏輯走一邊,發(fā)現上述算法的確得到25時是true循头,說明上述算法有誤绵估。
想了一下,素數分布在6的倍數的兩側卡骂,不是在左側就是在右側国裳,也有可能左右兩側都是素數(6的倍數的左右兩側都是素數時,我們將這兩個素數稱作孿生素數)全跨,在我們上述算法中缝左,根據上述思想進行了以6為步數的躍進,但是從7開始+6的躍進只遍歷了6的倍數的右側浓若,而忽略了6的左側渺杉,而并不是每一個6的倍數的右側數字是素數的時候,左側也一定是素數(反之亦然)挪钓。所以這種算法在4*6=24的左側23(是素數)是越、右側25(不是素數)時,出現了判斷錯誤碌上。
如何解決上述錯誤倚评?那就只能左右兩側都進行判斷,可是這樣一來馏予,算法是不是更加復雜天梧?還不如原始算法?霞丧?
走到這一步已經耗盡我的腦細胞了呢岗,所以戛然止步。如果有過路的讀者有想法或者更好的意見,歡迎留言批評指正敷燎!
溜了溜了~~~