简体   繁体   English

在Java中测试素数

[英]Testing for prime numbers in java

The goal of my program is to write a program that will prompt the user to input an integer. 我程序的目标是编写一个程序,提示用户输入整数。 The program will read the integer and decide whether it is a prime or not. 程序将读取整数并确定其是否为质数。 And if it is not a prime, it will tell the user all the divisors. 如果不是素数,它将告诉用户所有除数。

This is how far I have got, but when i tested it with numbers like 169 or 289, the program said that they were prime number. 这就是我所走的路,但是当我用169或289之类的数字对其进行测试时,程序说它们是质数。 I understand that the problem is lying on this line : 我了解问题出在这条线上:

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

I tried to do something like this : 我试图做这样的事情:

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

But it didn't work. 但这没有用。 A little help or a right direction would help a lot. 一点帮助或正确的方向会有所帮助。 Thank You! 谢谢!

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(",");}

                }

            } }

You're only trying numbers up to 9 for divisors. 您只想尝试除数最大为9的数字。 So anything that would have factors of all 10 or higher, such as 169 being 13 by 13, you will not find the 13s. 因此,所有具有等于或大于10的因子的东西,例如169是13乘13,您将找不到13。

Instead of storing the divisors in an array, consider using an integer and counting upwards. 不要将除数存储在数组中,而应考虑使用整数并向上计数。 That is to say, instead of div[j] just use j as your divisor, and don't let it stop at 10. Let it stop at the highest possible divisor (which is the square root of the number you're trying to find the prime of). 也就是说,不要将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>

If you don't actually need to do the calculations yourself (if this isn't homework, that is), you could always opt to use Java's BigInteger class. 如果您实际上不需要自己进行计算(也就是说,如果这不是家庭作业),则可以始终选择使用Java的BigInteger类。 For example: 例如:

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);
    }
}

As with most things in life, there are at least a couple caveats: 与生活中的大多数事物一样,至少有几点警告:

  1. the probability of reporting a number's primality is not 100%, nor can it be (but we'll talk about that in a moment); 报告数字素数的可能性不是100%,也不是(但是我们稍后再讨论); and

  2. the more accurate you want the test to be, the longer it will take. 您希望测试越准确,则需要的时间越长。

This is detailed in Oracle's Official Documentation : 这在Oracle的官方文档中有详细介绍:

isProbablePrime isProbablePrime

public boolean isProbablePrime (int certainty)

Returns true if this BigInteger is probably prime, false if it's definitely composite. 如果此BigInteger可能是素数,则返回true ;如果它绝对是复合true则返回false If certainty is <= 0 , true is returned. 如果certainty <= 0 ,则返回true

Parameters: 参数:

certainty - a measure of the uncertainty that the caller is willing to tolerate: if the call returns true the probability that this BigInteger is prime exceeds (1 - 1/(2^certainty)) . certainty -呼叫者愿意忍受的不certainty的度量:如果呼叫返回true ,则此BigInteger为质数的概率超过(1 - 1/(2^certainty)) The execution time of this method is proportional to the value of this parameter. 该方法的执行时间与该参数的值成比例。

Returns: 返回值:

true if this BigInteger is probably prime, false if it's definitely composite. true如果此BigInteger可能为素数, false ,如果它一定为合。

I got curious about how accurate it could be and how much time a highly-accurate primality test would take, so I made a quick benchmark and ran some numbers. 我对它的精确度和高精度的原始性测试需要多少时间感到好奇,因此我做了一个快速基准测试并得出了一些数字。

I calculated the primality of every odd number under a million for each certainty value between 1 and 50 (0 or less always returns true). 我针对1到50之间的每个确定性值(小于或等于0总是返回true)计算了百万以下的每个奇数的素数。

Times are in milliseconds (though the times were obtained via a call to System.nanoTime() , and then rounded to the nearest millisecond). 时间以毫秒为单位(尽管这些时间是通过调用System.nanoTime() ,然后四舍五入到最接近的毫秒)。

Here are my results: 这是我的结果:

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

As you can see, even at the highest certainty-value that I tested, evaluating the primality of 500,000 numbers only took 4 seconds and each evaluation had a 99.99999999999991% chance of being correct 如您所见,即使以我测试的最高确定性值,评估500,000个数字的素数也只用了4秒,每次评估都有99.99999999999991%的正确率

So if your intended application isn't incredibly performance-critical, you can use a (relatively) high number, like 25. The algorithm will correctly report a number as prime 99.99999701976776% of the time. 因此,如果您想要的应用程序不是非常关键的性能,则可以使用一个(相对)较高的数字,例如25。该算法将在正确的时间以99.99999701976776%的比率正确报告一个数字。 Not recommended if you're a rocket scientist. 如果您是火箭科学家,则不推荐使用。 And if you are , a rocket scientist, then I hope you find your solution elsewhere :). 如果您火箭科学家,那么我希望您在其他地方找到您的解决方案:)。

The reason you are getting 169 as a prime is because you are only dividing by the values 2-9 and 169 is 13 squared so it isn't divisible by any number 2-9. 之所以将169作为质数,是因为您仅将其除以2-9的值,而169为13的平方,因此不能被2-9整除。

you can use this method http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes to find all the prime numbers between 1 and n and use that to decide if your number is prime. 您可以使用此方法http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes查找所有介于1和n之间的质数,并使用该方法确定您的质数是否为质数。

A very easy and basic way to find if a number is prime is this: 查找数字是否为质数的一种非常简单且基本的方法是:

Continue dividing n by each number between 2 and n^1/2 inclusive. 继续用n除以2到n ^ 1/2之间的每个数字。 If any of them divide evenly, then n is not prime because you found a factor. 如果它们中的任何一个均分,则n不是质数,因为您找到了一个因子。 If n has no factors less than its square root, then n is prime. 如果n的因数不小于其平方根,则n为素数。 It is sufficient to check only for divisors less than or equal to n^1/2 because if n = a*b, then a and b can't both exceed the square root of 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