簡體   English   中英

在 Java 中查找素數

[英]Finding Prime Number in Java

我遇到了一個 Java 程序,它可以判斷給定的數字是否是素數。 這是代碼。

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

在這里,我不確定為什么在 for 循環中使用條件 i <= num/i 。 有人可以解釋一下嗎?

限制條件i <= num / i是性能優化:

給定例如num = 11i = 3 ,到目前為止,我們已經檢查了 11 是否可以除以 2(否),現在正在移動到 3,我們應該檢查它,答案是不能除以 3。現在我們正在移動到 4,我們還應該檢查 11 是否可以被它整除? 這樣的除法將產生 2.75,這是我們已經檢查過的小於 3 的值。 任何更高的i將產生更小的值,我們已經檢查過所有這些值,因此進一步檢查沒有意義。 我們現在知道答案了。

不要忘記,for(A;B;C)表達式A在循環開始時計算一次,表達式B從第一個循環開始計算,表達式C從第二個循環開始計算。

因此,最好是移動從B節偏差節。

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就像在做i <= sqrt(num)
如果 num 不是素數,我們可以將其分解為num = a * b
如果 num 的一個因子大於 num 的平方根,則另一個因子必須小於 num 的平方根。
如果兩者都大於它,那么它的乘積將大於 num。

這是檢查素數的更好方法

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

}

以下解決方案使用Sundaram 篩法打印出直到用戶提供的數字的所有質數:

請注意,對於大輸入,您可能會遇到 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));
        }
    }
}

在程序中添加 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); } }

是的。 for 循環的中間部分總是被評估,只有當評估給出真值時循環內容才會運行。 在您的情況下,循環將在第一個周期停止,因為 14/2 的模塊為 0,因此它將運行 if 主體,將布爾值設置為 false 並退出循環。

暫無
暫無

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

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