繁体   English   中英

Java:找出一个数是否是递归的质数

[英]Java: Find out if a number is prime recursively

我正在编写一个函数,如果数字是素数则返回真,否则返回假

这是我当前的代码:

    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”这样的数字,在那里我遇到内存不足错误。 我如何调整此代码以提高空间效率?

根本问题是递归不是正确的方法。 原始性测试不是一个递归问题,对于大量用户,您将始终很快超过可用存储。 我建议您在网络上进行有关“原始性测试”的研究。

关于确定问题是否递归的经验法则,我已经做了很久了,我不确定我能否表达出已经完全直观的内容,所以我会让别人去做。

但是,值得指出的是,一些数学上递归的问题具有计算解决方案,其中迭代远比幼稚的递归好得多。 素数(哈!)的例子是斐波那契数。 对于较大的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.StackOverflowError但这还不是故事的结尾。 大多数语言都会决定要分配给特定用途的内存量。 像Perl这样的稀有语言会将内存重新分配给最需要它的资源,而不会对程序的行为做任何假设。

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

如果你改变了三种int上述报关单long ,你就可以像测试数字2547487897L只要您展开堆栈或更大( -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));
}

暂无
暂无

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

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