面试问题:递归生成素数的最快方法是什么?

时间:2010-12-29 05:35:46

标签: java algorithm math primes

质数的生成很简单但是找到它并以递归方式生成(素数)的最快方法是什么?

这是我的解决方案。但是,这不是最好的方法。我认为它是O(N * sqrt(N))。如果我错了,请纠正我。

    public static boolean isPrime(int n) {
        if (n < 2) {
            return false;
        } else if (n % 2 == 0 & n != 2) {
            return false;
        } else {
            return isPrime(n, (int) Math.sqrt(n));
        }
    }

    private static boolean isPrime(int n, int i) {
        if (i < 2) {
            return true;
        } else if (n % i == 0) {
            return false;
        } else {
            return isPrime(n, --i);
        }
    }

   public static void generatePrimes(int n){
       if(n < 2) {
            return ;
       } else if(isPrime(n)) {
            System.out.println(n);
       } 

       generatePrimes(--n);

   }

   public static void main(String[] args) {

        generatePrimes(200);
   }

5 个答案:

答案 0 :(得分:4)

  

在数学方面,Atkin的筛子是一种快速,现代的算法,用于查找指定整数的所有素数。

Wikipedia article(包含伪代码)

为了解决递归问题,也许可以递归地实现Sieve of Eratosthenes。这个page可能会有所帮助,因为它似乎讨论了递归实现。

答案 1 :(得分:3)

对于recurrsion,您应该使用memoization来改善递归函数,意味着如果您找到素数将其保存在数组中,并且在调用isPrime(n)时首先检查数组中是否存在数字to isPrime(n,(int)Math.sqrt(n))。如果isPrime(n,i)返回true,则将其添加到prime列表中,最好将数组排序为二进制搜索,在C#中有排序列表,并且二进制搜索操作[使n项的列表取O(n log) n)和搜索是O(log(n))]我不知道java [但你可以实现它]。

编辑:您当前的方法是O(n sqrt(n))但是我的approch可以按相同的顺序排列!但是性能更好,实际上顺序是O(n sqrt(n) / log (n) + n log(n/log(n))),因为log(n)小于n^Epsilon,最好说它是O(n sqrt(n)),但正如你所看到它会运行log(n )时间更快。

同样最好不要i-2而且在启动时进行额外检查以更快地运行算法2 * log(n)。

答案 2 :(得分:3)

你需要的是Sieve of Forever,这里是递归主要测试人员的代码,我认为它非常有效,因为它只需要测试素因子,让我知道你的想法;)

顺便说一句,我不会尝试任何超过一个字节的东西,似乎需要一段时间才能超过100个。

public boolean isPrime(byte testNum)
{
    if ( testNum <= 1 )
        return false;
    for ( byte primeFactor = 2; primeFactor < testNum; primeFactor++ )
        if ( isPrime(primeFactor) )
            if ( testNum % primeFactor == 0 )
                return false;
    return true;
}

答案 3 :(得分:1)

首先,如果你想生成素数数字(而不是测试整数的素数)那么 Pocklington's theorem派上用场。如果你知道足够的p-1素因子,这个定理允许对候选p进行快速素性测试。因此,以下方法是可能的:生成一些素数,计算其产品的合适倍数并使用Pocklington定理进行测试。如果要查找大质数(例如RSA密码系统),则必须使用此方法递归来生成p-1的因子。

上面的描述缺少一些细节。但该方法已经深入分析。我认为这篇文章是最快的方法,如果发表的话,虽然有一段时间已经过去,有人可能已经改进了。

P.Mihailescu。 “使用算术进展中的搜索快速生成可证实的素数”,Proceedings CRYPTO 94,计算机科学讲义939,Springer 1994,第282-293页。

答案 4 :(得分:0)

为什么递归?

使用更好的素数生成算法,如Eratosthenes筛选,或者更好的阿特金筛选。