有没有很好的算法可以找到给定real
数字的最近素数?我只需要在前100个素数内搜索。
目前,我有一堆素数存储在一个数组中,我一次检查一个数字(O(n)?)。
答案 0 :(得分:17)
在给定目标相对较小的范围的情况下,不是排序的素数列表,而是有一个数组,该数组由范围内的所有奇数索引(你知道除了特殊情况2之外没有偶数素数)并且包含最接近的素数。找到解决方案的时间成为O(1)。
我认为第100个素数大约是541.所需要的是270 [小]整数的数组。
这种方法特别有效,因为相对较高的质数密度(特别是相对于奇数),在1,000以下的范围内。 (因为这会影响二叉树的大小)
答案 1 :(得分:11)
如果您只需搜索前100个素数,只需创建这些素数的有序表,然后进行二分搜索。这将使您获得一个素数,或两个之间的点,并检查哪一个更接近。
编辑:鉴于该范围内素数的分布,您可以通过使用插值搜索来加快速度(一点点) - 而不是始终从表格的中间开始,使用线性插值来猜测更准确的起点。第100个素数应该在250左右左右(猜测 - 我没有检查过),所以如果(例如)你想要一个最接近50的那个,那么你将开始大约1/5到达数组而不是中途。您可以将素数视为从1开始,因此只需将您想要的数字除以您范围内的最大值即可猜测起点。
答案 2 :(得分:8)
floor
和ceil
函数向上和向下舍入它以获得一个或两个候选答案。通过与这些数字的距离进行简单比较,可以得到非常快速的答案。
答案 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