2015-01-01 22 views
0

爲了避免任何誤解,我在這裏是新手,仍然是Java的初學者。我試圖編寫一個打印10,001st素數的代碼。代碼當前檢查數字是否可以被數字2-9(包括)整除,然後檢查數字的平方根是否是整數。查找10001素數 - 代碼沒有返回正確的數字

public static void main(String[] args){ 
    Integer Num , Counter; 
    Double Sqrt; //square root 
    Num=8; 
    Counter=4 ; 
    while(Counter<10001){ 
    Num++; 
    if ((Num%2!=0) && (Num%3!=0) && (Num%4!=0) && (Num%5!=0) && (Num%6!=0) && (Num%7!=0) && (Num%8!=0) && (Num%9!=0)){ 
    Sqrt = Math.sqrt(Num);  
    if(Sqrt%1!=0){ 
     Counter++; 
    } 
    } 
} 

System.out.println(Num); 
} 
} 

編輯:

我改變它,使它不再使用假的定義,但是這個新的代碼沒有輸出,我沒有看到與循環的任何問題。我也會嘗試下面的其他建議,但想知道如何解決這個問題。

public static void main(String[] args) 
    { 
int Num , Counter; 
double Sqrt; //square root 
Num=1; 
Counter=0 ; 

while(Counter<10001){ 
    Num++; 
    Sqrt = Math.sqrt(Num); 
    int i = (int)Sqrt; 
    while(i>1){ 
     if(Num%i==0){ //if the number is divisible then the loop is terminated and next number is tested 
     i=0; 
        } 
     i--; 
       } 

     if(i==1){ 
    Counter++; 
       } 
} 

System.out.println(Num); 
    } 
} 

謝謝。

+0

你的算法不正確。考慮數字11x13 = 143,這顯然不是素數,不是方數,也不能被2,3整除。 –

+0

@Michael謝謝你指出。我現在正在使用不同的算法。如果你可以看看它,那會很好。 – Abdul97

回答

1

您的新版本不起作用,因爲您正在測試從Math.sqrt(Num)降至1的所有數字,而不是所有數字降至2. 1總是正好進入每個數字,因此您的程序不會認爲任何數字是總理,並永遠運行。

要使其正常工作,您需要將while(i>0)更改爲while(i>1)。您還需要將if(i==0)更改爲if(i==1)。我也不確定爲什麼你的NumCounter的值是8和4.我會讓你弄清楚他們應該是什麼。

+0

感謝您的建議。我的'Counter'和'Num'分別是4和8(忘記分別將值改爲0和1)。 它現在的作品。謝謝您的幫助。 – Abdul97

+0

沒關係。我很高興聽到它的作品。 –

3

它不工作,因爲你的素數的定義不正確。

例如,數量437不是素數,因爲它是19 * 23,但它會通過您的電流試驗。

你的算法需要檢查有問題的數量不能被整除任何素數截至及包括你正在檢查的數量的平方根。

+0

關於如何改進/糾正它的任何建議?將測試數字是否可以通過數量小於其平方根的整數? – Abdul97

+0

是的,這是可行的,但它需要小於或等於,而不是小於。 – Amber

4

你的邏輯是有缺陷的。例如,當檢查數字143時,你的代碼認爲它是素數。但是,11 * 13 = 143,所以它實際上不是素數。我建議創建一個素數列表並通過列表進行for-each循環。

List<Integer> primes = new ArrayList<Integer>(); 
int number = 2; 
while (primes.size() < 10001) { 
    boolean isPrime = true; 
    for (Integer prime : primes) { 
     if (number % prime == 0) { 
     isPrime = false; 
     break; 
     } 
    } 
    if (isPrime) { 
     primes.add(number) 
    } 
    number++; 
} 
System.out.println(primes.get(10000)); 

這可能不是一個快速的解決方案,但它應該工作...雖然沒有測試。祝你好運 :)。

-1

我會使用基於埃拉托色尼的篩上的方法。問題是,既然你不知道10001素是什麼,你不知道你的陣列有多大。你可以試着想一些大數字,並希望它足夠大以容納10001個素數,但如果它太大,你會做額外的工作。可能有一些公式可以幫助你提出一個近似值,並從那裏開始。

另一種方法是,開始用較小的陣列,然後視需要擴展它。假設你從一個大小爲1000的布爾數組開始,表示數字1到1000.執行篩選(從2開始;將2加到列表中,標記數組中所有2的倍數,找到下一個未標記的值,將其添加到列表中,標記所有倍數等)。這顯然不會找到10001素數。因此,當你點擊布爾數組的末尾時,清除它,然後更改一個「基本」變量,以便它現在代表1001到2000範圍內的數字。檢查已經建立的素數列表,以及標記所有倍數。現在所有未標記的值都是素數。將它們添加到列表中,清除數組,然後更改基數,以使數組現在代表數字2001至3000.遍歷素數列表,標記倍數,並繼續前進,直到列表大小達到10001爲止。

我不知道這種方法與其他方法相比效率有多高,但直觀地看起來好像比逐一查看所有數字並檢查每個數字以獲得除數更好。

0

在這裏,您將找到另一種(緊湊)方法,用於生成由const MAX(生成的元素的數量)限制的素數序列,使用Stream類(對於生成的每個x,過濾器拒絕x不是僅通過X整除:一個數僅通過自身和1整除是素數):

public class PrimeNumbersSeq { 

    final private static Long MAX=10001l; 

    public static void main(String[] args) { 
    System.out.println(LongStream 
      .iterate(2, x -> x + 1) 
      .filter((i) -> LongStream.range(2, i) 
      .noneMatch(j -> i % j == 0)).limit(MAX) 
      .mapToObj(String::valueOf) 
      .collect(Collectors.joining(",", "[", "]"))); 
    } 
} 

輸出:[2,3,5,7,11,13,17,19,23,29,31,37 ,41,43,47,53,59,61,67,71,73,79,83,89,97,101 ...