簡體   English   中英

在Java中測試素數

[英]Testing for prime numbers in java

我程序的目標是編寫一個程序,提示用戶輸入整數。 程序將讀取整數並確定其是否為質數。 如果不是素數,它將告訴用戶所有除數。

這就是我所走的路,但是當我用169或289之類的數字對其進行測試時,程序說它們是質數。 我了解問題出在這條線上:

int[] div = new int[] { 2,3,4,5,6,7,8,9};

我試圖做這樣的事情:

for (int s = nr; s != 0 ; s--) { 
      if (nr%s == 0) {
      int[] div = new int[]{s}; }

但這沒有用。 一點幫助或正確的方向會有所幫助。 謝謝!

public static void main(String[] args){
    System.out.println("enter a number:");
    Scanner scanner = new Scanner (System.in);
    int nr = scanner.nextInt();
    int[] div = new int[] { 2,3,4,5,6,7,8,9}; 
    boolean prime = nr >= 2;
    int i = nr;
    for(int j = 0; j< div.length && prime && i> div[j]; j++)
        if(i % div[j] == 0)
            prime = false;

    if(prime){
        System.out.println(i + " is a prime");
    }else{
        System.out.print(i + " is divisible");
        for(int k = 2; k < i; k++)
            if(i % k == 0){
                System.out.print( k);
                System.out.print(",");}

                }

            } }

您只想嘗試除數最大為9的數字。 因此,所有具有等於或大於10的因子的東西,例如169是13乘13,您將找不到13。

不要將除數存儲在數組中,而應考慮使用整數並向上計數。 也就是說,不要將div[j]用作除數,而不要讓它在10處停止。讓它在盡可能高的除數處停止(這是您要嘗試計算的數字的平方根)找到素數)。

<edit> I should have looked a little closer... I guess it IS homework, so this answer is not really any good to you, eh? Well, I'm gonna leave it up in case the information here becomes useful to someone somewhere... </edit>

如果您實際上不需要自己進行計算(也就是說,如果這不是家庭作業),則可以始終選擇使用Java的BigInteger類。 例如:

public class Prime { 
    public static void main(String[] args){
        long start = System.nanoTime();
        System.out.println("enter a number:");
        Scanner scanner = new Scanner(System.in);
        BigInteger bigInt = scanner.nextBigInteger();
        boolean prime = bigInt.isProbablePrime(10);
        System.out.println(prime);
    }
}

與生活中的大多數事物一樣,至少有幾點警告:

  1. 報告數字素數的可能性不是100%,也不是(但是我們稍后再討論);

  2. 您希望測試越准確,則需要的時間越長。

這在Oracle的官方文檔中有詳細介紹:

isProbablePrime

public boolean isProbablePrime (int certainty)

如果此BigInteger可能是素數,則返回true ;如果它絕對是復合true則返回false 如果certainty <= 0 ,則返回true

參數:

certainty -呼叫者願意忍受的不certainty的度量:如果呼叫返回true ,則此BigInteger為質數的概率超過(1 - 1/(2^certainty)) 該方法的執行時間與該參數的值成比例。

返回值:

true如果此BigInteger可能為素數, false ,如果它一定為合。

我對它的精確度和高精度的原始性測試需要多少時間感到好奇,因此我做了一個快速基准測試並得出了一些數字。

我針對1到50之間的每個確定性值(小於或等於0總是返回true)計算了百萬以下的每個奇數的素數。

時間以毫秒為單位(盡管這些時間是通過調用System.nanoTime() ,然后四舍五入到最接近的毫秒)。

這是我的結果:

Certainty       Time(ms)        Chance of Correctness
1               1417            50.0%
2               932             75.0%
3               1064            87.5%
4               1063            93.75%
5               1183            96.875%
6               1195            98.4375%
7               1313            99.21875%
8               1308            99.609375%
9               1441            99.8046875%
10              1443            99.90234375%
11              1567            99.951171875%
12              1571            99.9755859375%
13              1690            99.98779296875%
14              1691            99.993896484375%
15              1817            99.9969482421875%
16              1822            99.99847412109375%
17              1944            99.99923706054688%
18              1941            99.99961853027344%
19              2069            99.99980926513672%
20              2073            99.99990463256836%
21              2197            99.99995231628418%
22              2200            99.99997615814209%
23              2324            99.99998807907104%
24              2340            99.99999403953552%
25              2453            99.99999701976776%
26              2465            99.99999850988388%
27              2647            99.99999925494194%
28              2626            99.99999962747097%
29              2715            99.99999981373549%
30              2710            99.99999990686774%
31              2844            99.99999995343387%
32              2818            99.99999997671694%
33              2950            99.99999998835847%
34              3074            99.99999999417923%
35              3121            99.99999999708962%
36              3167            99.99999999854481%
37              3295            99.9999999992724%
38              3302            99.9999999996362%
39              3334            99.9999999998181%
40              3360            99.99999999990905%
41              3493            99.99999999995453%
42              3583            99.99999999997726%
43              3663            99.99999999998863%
44              3599            99.99999999999432%
45              3783            99.99999999999716%
46              3816            99.99999999999858%
47              3964            99.99999999999929%
48              3898            99.99999999999964%
49              4029            99.99999999999982%
50              3969            99.99999999999991%
total: 124312

如您所見,即使以我測試的最高確定性值,評估500,000個數字的素數也只用了4秒,每次評估都有99.99999999999991%的正確率

因此,如果您想要的應用程序不是非常關鍵的性能,則可以使用一個(相對)較高的數字,例如25。該算法將在正確的時間以99.99999701976776%的比率正確報告一個數字。 如果您是火箭科學家,則不推薦使用。 如果您火箭科學家,那么我希望您在其他地方找到您的解決方案:)。

之所以將169作為質數,是因為您僅將其除以2-9的值,而169為13的平方,因此不能被2-9整除。

您可以使用此方法http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes查找所有介於1和n之間的質數,並使用該方法確定您的質數是否為質數。

查找數字是否為質數的一種非常簡單且基本的方法是:

繼續用n除以2到n ^ 1/2之間的每個數字。 如果它們中的任何一個均分,則n不是質數,因為您找到了一個因子。 如果n的因數不小於其平方根,則n為素數。 僅檢查小於或等於n ^ 1/2的除數就足夠了,因為如果n = a * b,則a和b都不能都超過n的平方根。

for(int i=2;i<=n^1/2;i++) 
  {
   if(num%i)==0 //number not prime
    else continue;
  }

  if none of the if statements in the loop were true, number is prime

只需使用Java內置的BigInteger.isProbablePrime()庫函數即可。雖然不是100%確定如何使用確定性參數。

BigInteger.valueOf(13).isProbablePrime(10000)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM