如何找到大于给定数字的最小素数?例如,给定4,我需要5; 给出7,我需要11.
我想知道有关最佳算法的一些想法.我想到的一种方法是通过Eratosthenes筛子生成素数,然后在给定数字后找到素数.
Raj*_*pal 25
资料来源:维基百科
Bertrand的假设(实际上是一个定理)指出,如果n> 3是一个整数,那么总是存在至少一个素数p,n <p <2n - 2.一个较弱但更优雅的公式是:每n> 1总是至少有一个素数p,使得n <p <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
}
}
Run Code Online (Sandbox Code Playgroud)
已经提出了一些其他方法,我认为它们很好,但它实际上取决于您希望在现场存储或计算多少.例如,如果您在非常大的数字之后寻找下一个素数,那么使用Eratosthenes的Sieve可能不会那么好,因为您需要存储的位数.
或者,您可以检查(和包括)3和sqrt(N)之间的所有奇数整数,每个数字奇数N大于输入数字,直到找到正确的数字.当然,当你发现它是复合材料时,你可以停止检查.
如果你想要一个不同的方法,那么我建议对输入数字以上的所有奇数(假设输入> 1)使用Miller-Rabin素性检验,直到找到素数.如果您按照位于页面底部的列表中的数字a
来检查给定范围,则可以显着减少a
需要检查的数量.当然,在与Miller-Rabin核实之前,您可能想要检查至少一些较小的素数(例如3,5,7,11).
我之前做过这个.
只有加入Bejerand的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;
}
Run Code Online (Sandbox Code Playgroud)