JAVA中素数的递归方法

时间:2015-12-06 02:31:01

标签: java recursion boolean

首先,我知道这是一个简单的问题,我是初学者所以请耐心等待。 我一直在用Java练习这个练习,而且我正在练习测试,而这一点真的搞砸了我的自信心。 所以无论如何问题看起来像这样

 // Returns true if (and only if) n is a prime number;  n > 1 is assumed.
private static boolean isPrime(long n) {
    return isPrime(n, 2);
    // See the method isPrime below.
}

// Helper method for isPrime ...
private static boolean isPrime(long n, long m) {
    return (m * n > (m /* TODO: modify expression if necessary */))
            || (n % m == (0 /* TODO: modify expression if necessary */)
                && isPrime((m /* TODO: modify expression if necessary */), n + 1));
}

所以你应该在TODO所在的括号内填写这些表达式。 我的问题是我无法追踪它的作用。

isPrime((.....),n+1); 

如果有人可以就如何开始解决这个问题提出一些建议,我将非常感激。

1 个答案:

答案 0 :(得分:2)

此问题不适用于递归解决方案。或者至少不是高效的递归解决方案。

primality的定义是,如果N不能被除了它本身之外的任何正整数整除,则N是素数。使用递归处理它的常规方法是定义一个递归的“is_divisible”函数:

# for integers m >= 1
is_prime(m):
    return is_divisible(m, 1)

is_divisible(m, n):
    if n >= m: return true
    if n == 1: return is_divisible(m, n + 1)
    if m % n == 0: return false  // HERE
    return is_divisible(m, n + 1)

OR(更高效的3参数版本)

# for all integers m
is_prime(m):
    if m == 1: return false
    if m >= 2: return is_divisible(m, sqrt(m), 2)
    error "m is not a positive integer"

is_divisible(m, max, n) :
    if n >= max: return true
    if m % n == 0: return false  // HERE
    return is_divisible(m, max, n + 1)

(在文献中,他们经常将函数称为is_divisible“辅助”函数。这是函数式编程中的常用工具。)

如果你试图“优化”只考虑HERE处的素数,你最终会得到双递归和指数复杂性。

这在Java中非常“不自然”,并且效率非常低(甚至与使用循环 1 的初始素性测试相比)因为Java不进行递归的尾调用优化。实际上,如果足够大N,您将获得StackOverflowError

1 - 一个更好但仍然简单的方法是Erathones筛选。虽然它们相当复杂,并且在某些情况下是概率性的,但是有更好的质量测试,尽管它们很复杂。