Java:递归判断一个数是否为素数

Java: Find out if a number is prime recursively

我正在编写一个函数,returns如果一个数是素数则为真,否则为假

这是我当前的代码:

    public static boolean checkPrime(int n, int currDivisor){
        if(n < 2){
            return true;
        }
        if(currDivisor == (n/2)){
            return true;
        }
        else if(n % currDivisor == 0 ){
            return false;           
        }
        else{
            return checkPrime(n, currDivisor + 1);
        }
    }

    public static void main(String[] args){
        System.out.println(checkPrime(23352, 2));
    }

它适用于很多测试用例,除了像“1000000007”这样的数字,我会遇到内存不足错误。我如何调整此代码以提高 space 的效率?

根本问题是递归不是正确的方法。素数测试不是递归问题,对于大量数据,您总是会很快超出可用存储空间。我建议你在网上做一些关于 "primality testing".

的研究

关于判断一个问题是否递归的经验法则,我已经这样做了很长时间,我不确定我是否可以表达已经变得完全直观的东西,所以我会让别人来做.

但是,值得指出的是,一些数学上递归的问题具有计算解决方案,其中迭代远比朴素递归好得多。主要(哈!)的例子是斐波那契数列。对于大 n,简单的递归解决方案会占用内存并执行冗余计算,而迭代解决方案则更快更好。

我看到的第一个问题是您的程序存在错误。似乎认为 0、1 和 4 是素数而 3 不是。我看到的第二个问题是,它在递归之前没有正确处理简单情况,这是在浪费堆栈帧。这是我对您的代码的修改:

public static boolean checkPrime(int n) {
    return checkPrime1(n, 3);
}

public static boolean checkPrime1(int n, int currDivisor) {
    if (n < 2) {
        return false;
    }

    if (n % 2 == 0) {
        return (n == 2);
    }

    if (currDivisor * currDivisor > n) {
        return true;
    }

    if (n % currDivisor == 0) {
        return false;
    }

    return checkPrime1(n, currDivisor + 2);
}

就处理而言:

System.out.println(checkPrime(1000000007));

您仍然会得到 java.lang.WhosebugError,但这还没有结束。大多数语言都会决定为特定目的分配多少内存。像 Perl 这样罕见的语言会将内存重新分配给最需要它的任何资源,而不对程序的行为方式做出假设。

您可以更改分配给 Java 堆栈的内存量——使用 -Xss2m 参数调用 java 会分配足够的额外堆栈让您测试 1000000007 (true, 顺便说一下。)

如果将上面的三个 int 声明更改为 long,只要展开堆栈 (-Xss4m 在这种情况下。)

我并不是说这是递归的好问题,它不是。但是,如果您要使用递归,请明智地使用它。差劲的递归使递归名声不好。有低效的递归 Fibonnaci 算法(通常是双递归)和高效的(单递归)算法。递归代码通常最适合递归数据。

一些语言,还没有Java一致,可以将上面的代码优化为尾递归,并使其有效地迭代性能。

    /*by mostafa asem aljbali*/
    static boolean isPrime(int num, int i){

        if (num <= 2){
            return (num == 2) ? true : false;
        }
        if (num % i == 0){
            return false;
        }
        if (i * i > num){
            return true;
        }

        return isPrime(num , (i + 1));
    }
 public static void main(String[] args){
    System.out.println("Is Prime: "+ isPrime(7, 2));
}