如何找到最近的素数?

时间:2009-10-15 21:12:55

标签: algorithm primes

有没有很好的算法可以找到给定real数字的最近素数?我只需要在前100个素数内搜索。

目前,我有一堆素数存储在一个数组中,我一次检查一个数字(O(n)?)。

14 个答案:

答案 0 :(得分:17)

在给定目标相对较小的范围的情况下,不是排序的素数列表,而是有一个数组,该数组由范围内的所有奇数索引(你知道除了特殊情况2之外没有偶数素数)并且包含最接近的素数。找到解决方案的时间成为O(1)。

我认为第100个素数大约是541.所需要的是270 [小]整数的数组。

这种方法特别有效,因为相对较高的质数密度(特别是相对于奇数),在1,000以下的范围内。 (因为这会影响二叉树的大小)

答案 1 :(得分:11)

如果您只需搜索前100个素数,只需创建这些素数的有序表,然后进行二分搜索。这将使您获得一个素数,或两个之间的点,并检查哪一个更接近。

编辑:鉴于该范围内素数的分布,您可以通过使用插值搜索来加快速度(一点点) - 而不是始终从表格的中间开始,使用线性插值来猜测更准确的起点。第100个素数应该在250左右左右(猜测 - 我没有检查过),所以如果(例如)你想要一个最接近50的那个,那么你将开始大约1/5到达数组而不是中途。您可以将素数视为从1开始,因此只需将您想要的数字除以您范围内的最大值即可猜测起点。

答案 2 :(得分:8)

到目前为止,考虑到手头的任务,答案相当复杂。前100个素数are all less then 600。我将创建一个大小为600的数组,并将每个最接近的素数值放在该数字中。然后,给定一个要测试的数字,我会使用floorceil函数向上和向下舍入它以获得一个或两个候选答案。通过与这些数字的距离进行简单比较,可以得到非常快速的答案。

答案 3 :(得分:3)

最简单的方法是将素数存储在排序列表中,并修改算法以进行二分查找。

标准二进制搜索算法将为未命中返回null,但应该直接修改它以用于您的目的。

答案 4 :(得分:3)

最快的算法?使用p [100] = 541个元素创建一个查找表,并返回floor(x)的结果,并在[2,3]上使用x的特殊逻辑。那将是O(1)。

答案 5 :(得分:2)

您应该在数组中对您的号码进行排序,然后您可以使用binary search。在最坏的情况下,该算法的性能为O(log n)。

答案 6 :(得分:1)

public static boolean p(int n){

    for(int i=3;i*i<=n;i+=2) {
        if(n%i==0)
            return false;
    }
    return n%2==0? false: true; }

public static void main(String args[]){
    String n="0";
    int x = Integer.parseInt(n);
    int z=x;
    int a=0;
    int i=1;
    while(!p(x)){

      a = i*(int)Math.pow(-1, i);
      i++;
      x+=a;
    }

    System.out.println( (int) Math.abs(x-z));}

这是针对n&gt; = 2。

答案 7 :(得分:1)

在python中:

>>> def nearest_prime(n):
    incr = -1
    multiplier = -1
    count = 1
    while True:
        if prime(n):
            return n
        else:
            n = n + incr
            multiplier = multiplier * -1
            count = count + 1
            incr = multiplier * count

>>> nearest_prime(3)
3
>>> nearest_prime(4)
3
>>> nearest_prime(5)
5
>>> nearest_prime(6)
5
>>> nearest_prime(7)
7
>>> nearest_prime(8)
7
>>> nearest_prime(9)
7
>>> nearest_prime(10)
11

答案 8 :(得分:1)

<?php
$N1Diff = null;
$N2Diff = null;

$n1 = null;
$n2 = null;

$number = 16;

function isPrime($x) {

    for ($i = 2; $i < $x; $i++) {
        if ($x % $i == 0) {
            return false;
        }
    }

    return true;
}


for ($j = $number; ; $j--) {

    if( isPrime($j) ){
       $N1Diff = abs($number - $j);
       $n1 = $j;
       break;
    }
}


for ($j = $number; ; $j++) {

    if( isPrime($j) ){
       $N2Diff = abs($number - $j);
       $n2 = $j;
       break;
    }

}

if($N1Diff < $N2Diff) {

    echo $n1;

} else if ($N1Diff2 < $N1Diff ){
    echo $n2;
}

答案 9 :(得分:0)

如果您想编写算法,维基百科搜索prime number会引导我阅读Sieve of Eratosthenes上的另一篇文章。该算法看起来有点简单,我认为递归函数很适合它。 (我可能错了。)

答案 10 :(得分:0)

如果阵列解决方案不是适合您的解决方案(对于您的方案而言是最佳解决方案),您可以尝试以下代码。在“2或3”情况之后,它将检查远离起始值的每个奇数,直到找到素数。


static int NearestPrime(double original)
{
    int above = (int)Math.Ceiling(original);
    int below = (int)Math.Floor(original);

    if (above <= 2)
    {
        return 2;
    }

    if (below == 2)
    {
        return (original - 2 < 0.5) ? 2 : 3;
    }

    if (below % 2 == 0) below -= 1;
    if (above % 2 == 0) above += 1;

    double diffBelow = double.MaxValue, diffAbove = double.MaxValue;

    for (; ; above += 2, below -= 2)
    {
        if (IsPrime(below))
        {
            diffBelow = original - below;
        }

        if (IsPrime(above))
        {
            diffAbove = above - original;
        }

        if (diffAbove != double.MaxValue || diffBelow != double.MaxValue)
        {
            break;
        }
    }

    //edit to your liking for midpoint cases (4.0, 6.0, 9.0, etc)
    return (int) (diffAbove < diffBelow ? above : below);
}

static bool IsPrime(int p)  //intentionally incomplete due to checks in NearestPrime
{
    for (int i = 3; i < Math.Sqrt(p); i += 2)
    {
        if (p % i == 0)
            return false;
    }

    return true;
}

答案 11 :(得分:0)

查找表,大小为100字节; (未签名的字符) 圆实数并使用查找表。

答案 12 :(得分:0)

最简单的答案 - 每个素数都可以表格形式表示(6 * x-1和6 * X +1)(2和3除外)。 让数字是N.divide它与6。 T = N / 6; 现在 A =(T-1)* 6 B =(T + 1)* 6 并检查哪一个更靠近N.

答案 13 :(得分:0)

也许我们可以找到左边和右边最接近的素数,然后进行比较以获得最接近的素数。 (我假设下一个素数会在接下来的10次出现中出现)

def leftnearestprimeno(n):
    n1 = n-1
    while(n1 >= 0):
        if isprime(n1):
            return n1
        else:
            n1 -= 1
    return -1

def rightnearestprimeno(n):
    n1 = n+1
    while(n1 < (n+10)):
        if isprime(n1):
            return n1
        else:
            n1 += 1

    return -1


n = int(input())
a = leftnearestprimeno(n)
b = rightnearestprimeno(n)
if (n - a) < (b - n):
    print("nearest: ", a)
elif (n - a) > (b - n):
    print("nearest: ", b)
else: 
    print("nearest: ", a)        #in case the difference is equal, choose min 
                                 #value