找到给定数字后的素数

时间:2010-03-18 08:44:36

标签: algorithm primes

如何找到大于给定数字的最小素数?例如,给定4,我需要5;给出7,我需要11。

我想知道有关最佳算法的一些想法。我想到的一种方法是通过Eratosthenes筛子生成素数,然后在给定数字后找到素数。

7 个答案:

答案 0 :(得分:24)

来源维基百科

  

Bertrand's postulate(实际上是一个定理)指出如果n> 3是整数,则总是存在至少一个素数p,其中n <1。 p&lt; 2n - 2.较弱但更优雅的配方是:对于每个n> 2。在图1中,总是存在至少一个素数p,使得n <1。 p&lt; 2n个。

所以如果给我一个数字,比如n,我可以检查范围(n,2 * n)[不包括n和2 * n的开放区间]

int GetNextPrime(int n)
{
    bool isPrime = false;
    for (int i = n; i < 2 * n; ++i)
    {
    // go with your regular prime checking routine
    // as soon as you find a prime, break this for loop
    }
}

答案 1 :(得分:7)

已经提出了一些其他方法,我认为它们很好,但它实际上取决于您希望在现场存储或计算的数量。例如,如果您在非常大的数字之后寻找下一个素数,那么使用Eratosthenes的Sieve可能不会那么好,因为您需要存储的位数。

或者,您可以检查(和包括)3和sqrt(N)之间的所有奇数整数,每个数字奇数N大于输入数字,直到找到正确的数字。当然,当你发现它是复合材料时,你可以停止检查。

如果你想要一个不同的方法,那么我建议在输入数字之上的所有奇数上使用Miller-Rabin primality test(假设输入为> 1),直到找到一个素数。如果您按照位于页面底部的列表a来查看给定范围,则可以显着减少需要检查的a个数。当然,在与Miller-Rabin核实之前,您可能想要检查至少一些较小的素数(例如3,5,7,11)。

答案 2 :(得分:7)

我以前做过这个。

只有来自Rajendra's Answer的Bertrand定理。

来自topcoder的现成代码。

#include<iostream>
using namespace std;

/* This function calculates (ab)%c */
int modulo(int a,int b,int c){
    long long x=1,y=a; // long long is taken to avoid overflow of intermediate results
    while(b > 0){
        if(b%2 == 1){
            x=(x*y)%c;
        }
        y = (y*y)%c; // squaring the base
        b /= 2;
    }
    return x%c;
}

/* this function calculates (a*b)%c taking into account that a*b might overflow */
long long mulmod(long long a,long long b,long long c){
    long long x = 0,y=a%c;
    while(b > 0){
        if(b%2 == 1){
            x = (x+y)%c;
        }
        y = (y*2)%c;
        b /= 2;
    }
    return x%c;
}

/* Miller-Rabin primality test, iteration signifies the accuracy of the test */
bool Miller(long long p,int iteration){
    if(p<2){
        return false;
    }
    if(p!=2 && p%2==0){
        return false;
    }
    long long s=p-1;
    while(s%2==0){
        s/=2;
    }
    for(int i=0;i<iteration;i++){
        long long a=rand()%(p-1)+1,temp=s;
        long long mod=modulo(a,temp,p);
        while(temp!=p-1 && mod!=1 && mod!=p-1){
            mod=mulmod(mod,mod,p);
            temp *= 2;
        }
        if(mod!=p-1 && temp%2==0){
            return false;
        }
    }
    return true;
}

int main(int argc, char* argv[])
{

    int input = 1000;
    int i = 0;

    if(input%2==0)
        i = input+1;
    else i = input;

    for(;i<2*input;i+=2) // from Rajendra's answer
        if(Miller(i,20)) // 18-20 iterations are enough for most of the applications.
            break;
    cout<<i<<endl;

    return 0;
}

答案 3 :(得分:2)

我通常会看到两种方法。

  • 从n开始计数并检查每个号码是否为素数
  • 生成素数并检查它们。 (也许事先这样做,使用现有的primenumber表,所以你不需要每次都计算东西(只要N在你预先计算的表的范围内)

也许这也有帮助,(简单地用你给定的数字替换2,用无限替换N:D) finding all prime numbers between 2 and N

答案 4 :(得分:1)

我有一个很大的查找表,然后搜索给定的数字并回复序列中的下一个。

如果给定数字的范围存在已知(明智的)上限,则效果很好。

答案 5 :(得分:0)

<form method="post" oninput="priceCalc();">
  <div class="item-option">
    <label class="label">
      <input type="checkbox" name="checkbox" value="text" id="opt1"> Uranium $3000
    </label>
  </div>
  <div class="price">
    <h3>Total estimated price: </h3>
    <p id="totalPrice">$0.00</p>
  </div>
</form>

答案 6 :(得分:-1)

private static int nextPrime(int num) {
        num++;
        for (int i = 2; i <num; i++) {
            if(num%i == 0) {
                num++;
                i=2;
            } else{
                continue;
            }
        }
        return num;
    }