【问题标题】:Finding a prime number after a given number在给定数字之后查找质数
【发布时间】:2011-01-28 22:21:49
【问题描述】:

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

我想知道一些关于最佳算法的想法。我想到的一种方法是通过埃拉托色尼筛生成素数,然后找到给定数之后的素数。

【问题讨论】:

  • 这与算法/编程有关。为什么关门了?
  • 由于没有人认为适合解释为什么他们关闭了它,我投票决定重新开放。这对我来说似乎不是题外话。
  • 应该强制“关闭者”至少揭示关闭的原因!
  • 直接在下方说明他们选择关闭它的原因。在这种情况下关闭为题外话。我已经投票支持重新开放,因为它似乎对我来说并不离题。
  • 您想重新考虑您接受的答案吗? :-)

标签: algorithm primes


【解决方案1】:

来源维基百科

Bertrand's postulate(实际上是一个定理)指出如果 n > 3 是一个整数,那么总是存在至少一个 n 1 总是存在至少一个素数 p 使得 n

所以如果给我一个数字,比如 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
    }
}

【讨论】:

  • 那么,如果你保证在循环结束之前找到一个素数,那么这不能只是一个while(true) 并消除所有的比较吗?
  • @Neil:好主意!将其发布为答案。
  • 时间复杂度太高
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    我以前做过。

    唯一的加法是来自Rajendra's Answer 的伯特兰定理。

    还有来自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;
    }
    

    【讨论】:

      【解决方案4】:

      我通常看到两种方法来做到这一点。

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

      也许这也有帮助,(只需将 2 替换为给定的 Number 并将 N 替换为无限 :D ) finding all prime numbers between 2 and N

      【讨论】:

        【解决方案5】:

        我会有一个大的查找表,然后在它上面搜索给定的数字,然后用序列中的下一个来响应。

        如果给定数字的范围有一个已知(合理的)上限,则效果很好。

        【讨论】:

        • 想一想,如果我想找到一个最接近的 N 的大素数,其类型为 unsigned long,那么查找表可能没有那么多条目。
        • 这是我的第二句话。
        【解决方案6】:
                int length = number;
                bool flag = true;
                for (int i = number; i <= length; i++)
                {
                    for (int k = 2; k < length; k++)
                    {
                        if (i != k && i % k == 0)
                        {
                            flag = false;
                            length = length + 1;
                            break;
                        }
                    }
        
                    if (flag)
                    {
                        Console.WriteLine(i);
                    }
                    flag = true;
                }
        

        【讨论】:

        • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
        【解决方案7】:
        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;
            }
        

        【讨论】:

        • 存在时间复杂度问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-05
        相关资源
        最近更新 更多