简体   繁体   English

在 Java 中查找素数

[英]Finding Prime Number in Java

I came across a Java program which finds whether the given number is a prime.我遇到了一个 Java 程序,它可以判断给定的数字是否是素数。 here is the code.这是代码。

class FindPrime {
    public static void main(String args[]) {
        int num;
        boolean isPrime;
        num = 14;

        if (num < 2) 
          isPrime = false;
        else 
          isPrime = true;

        for (int i = 2; i <= num / i; i++) {
            if ((num % i) == 0) {
                isPrime = false;
                break;
            }
        }
        if (isPrime) 
          System.out.println("Prime");
        else 
          System.out.println("Not Prime");
    }
}

Here, I'm not sure why the condition i <= num/i is used in the for loop.在这里,我不确定为什么在 for 循环中使用条件 i <= num/i 。 Can someone please explain me?有人可以解释一下吗?

The limiting condition i <= num / i is a performance optimisation:限制条件i <= num / i是性能优化:

Given eg num = 11 and i = 3 , we have so far checked if 11 can be divided by 2 (no) and now are moving to 3 and we should check it, the answer is no it cannot be divided by 3. Now we are moving to 4, should we still check if 11 can be divided by it?给定例如num = 11i = 3 ,到目前为止,我们已经检查了 11 是否可以除以 2(否),现在正在移动到 3,我们应该检查它,答案是不能除以 3。现在我们正在移动到 4,我们还应该检查 11 是否可以被它整除? Such a division will yield 2.75, a value smaller than 3 that we have already checked.这样的除法将产生 2.75,这是我们已经检查过的小于 3 的值。 Any higher i will yield even smaller values all of which we have already checked, so there is no sense checking further.任何更高的i将产生更小的值,我们已经检查过所有这些值,因此进一步检查没有意义。 We know the answer by now.我们现在知道答案了。

Do not forget, that for loop like for(A;B;C) expression A is calculated once at the beginning of the loop, expression B is calculated every loop starting from first, expression C is calculated started from second loop.不要忘记,for(A;B;C)表达式A在循环开始时计算一次,表达式B从第一个循环开始计算,表达式C从第二个循环开始计算。

So it is better to move deviation from section B to section A .因此,最好是移动从B节偏差节。

i < num / i is performance optimization, moreover it is enough to check first Math.sqrt(num) elements. i < num / i是性能优化,而且检查第一个Math.sqrt(num)元素就足够了。

public static boolean isPrime(int val) {
    if (val < 2)
        return false;

    for (int i = 2, max = (int)Math.sqrt(val); i <= max; i++)
        if (val % i == 0)
            return false;

    return true;
}

i <= num/i it's like doing i <= sqrt(num) . i <= num/i就像在做i <= sqrt(num)
If num is not a prime, we can factorize it into num = a * b .如果 num 不是素数,我们可以将其分解为num = a * b
If a factor of num is greater then the the square root of num, the other one must be less then the square root of num.如果 num 的一个因子大于 num 的平方根,则另一个因子必须小于 num 的平方根。
If both were greater than it, then its product would be greater than num.如果两者都大于它,那么它的乘积将大于 num。

This is the better way to check the prime number or not这是检查素数的更好方法

package com.practice.competitive.maths;

import java.util.Scanner;

public class CheckPrime {

    public static void main(String[] args) {

        try(Scanner scanner = new Scanner(System.in)) {
            int testCases = scanner.nextInt();
            long number = scanner.nextLong();
            String result = compute(number);
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String compute(long number) {
        if(number > 0 &&  number % 2 == 0)
            return "No";
        long sqrt = floorSqrt(number);
        for(long i = 3; i<sqrt;i+=2) {
            if(number % i == 0)
                return "No";
        }
        return "Yes";
    }

    private static long floorSqrt(long number) {
        if(number == 0 || number == 1)
            return number;
        long start = 0;
        long end = number;
        long answer = 0;
        while (start <= end) {
            long mid = (start + end)/2;
            if(mid*mid == number)
                return mid;
            if(mid*mid < number) {
                start = mid+1;
                answer = mid;
            }else {
                end = mid-1;
            }
        }
        return answer;
    }

}

The below solution prints out all prime numbers up to the number provided by the user, using the Sieve of Sundaram :以下解决方案使用Sundaram 筛法打印出直到用户提供的数字的所有质数:

Note, that you might have an OutOfMemoryError for a large input.请注意,对于大输入,您可能会遇到 OutOfMemoryError。

public static void isPrime(int num) {
    int k = (num - 2) / 2;
    int[] a = new int[k + 1];
    for (int i = 1; i < k + 1; i++) {
        int j = i;
        while ((i + j + 2 * i * j) <= k) {
            a[i + j + 2 * i * j] = 1;
            j += 1;
        }
    }
    if (num > 2) {
        System.out.println(2);
    }

    for (int l = 1; l < k + 1; l++) {
        if (a[l] == 0) {
            System.out.println((2 * l + 1));
        }
    }
}

it is not wise to add for loops in the program since they give ua time complexity which is greater O(n) linear time complexity but if statements would be wise here is an example在程序中添加 for 循环是不明智的,因为它们给出了 ua 时间复杂度,这是更大的 O(n) 线性时间复杂度,但如果语句是明智的,这里是一个例子

 // code contributed by akoyama koke public class prime { public static void main(String[] args) { int []arry={1,23,71,3,4,5,6,8,21}; int n=arry[8]; if(n%2==0) { System.out.print("number is even:"+" "+n); } else if(n%2!=0) { if(n%3!=0 && n%5!=0 && n%7!=0) { System.out.print("number is prime:"+" "+n); } else { System.out.print("number is odd and not prime:"+" "+n); } } else System.out.println("number either decimal or a negative not catared for:"+" "+n); } }

yes it is.是的。 The middle part of the for loop is always evaluated and the loop content runs only if the evaluation give a true value. for 循环的中间部分总是被评估,只有当评估给出真值时循环内容才会运行。 In your case, the loop will stop on its first cycle since the module of 14/2 is 0, therefore it will run the if body which set the boolean to false and exit the loop.在您的情况下,循环将在第一个周期停止,因为 14/2 的模块为 0,因此它将运行 if 主体,将布尔值设置为 false 并退出循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM