给您一个数字n(3 <= n <10 ^ 6),您必须找到小于n的最接近素数?
例子:
Input : n = 10
Output: 7
Input : n = 17
Output: 13
Input : n = 30
Output: 29
解决此问题的简单方法是将n-1迭代为2,并针对每个数字检查其是否为质数。如果是素数,则将其返回并中断循环。如果只有一个查询,则此解决方案看起来不错。但是,如果有多个查询不同的n值,则效率不高。
解决此问题的有效方法是使用Sundaram的Sieve生成少于10 ^ 6的所有素数,然后以递增顺序存储在数组中。现在,应用修改后的二进制搜索来搜索小于n的最接近素数。该解决方案的时间复杂度为O(n log n + log n)= O(n log n)。
C++
// C++ program to find the nearest prime to n.
#include
#define MAX 1000000
using namespace std;
// array to store all primes less than 10^6
vector primes;
// Utility function of Sieve of Sundaram
void Sieve()
{
int n = MAX;
// In general Sieve of Sundaram, produces primes
// smaller than (2*x + 2) for a number given
// number x
int nNew = sqrt(n);
// This array is used to separate numbers of the
// form i+j+2ij from others where 1 <= i <= j
int marked[n/2+500] = {0};
// eliminate indexes which does not produce primes
for (int i=1; i<=(nNew-1)/2; i++)
for (int j=(i*(i+1))<<1; j<=n/2; j=j+2*i+1)
marked[j] = 1;
// Since 2 is a prime number
primes.push_back(2);
// Remaining primes are of the form 2*i + 1 such
// that marked[i] is false.
for (int i=1; i<=n/2; i++)
if (marked[i] == 0)
primes.push_back(2*i + 1);
}
// modified binary search to find nearest prime less than N
int binarySearch(int left,int right,int n)
{
if (left<=right)
{
int mid = (left + right)/2;
// base condition is, if we are reaching at left
// corner or right corner of primes[] array then
// return that corner element because before or
// after that we don't have any prime number in
// primes array
if (mid == 0 || mid == primes.size()-1)
return primes[mid];
// now if n is itself a prime so it will be present
// in primes array and here we have to find nearest
// prime less than n so we will return primes[mid-1]
if (primes[mid] == n)
return primes[mid-1];
// now if primes[mid]n that
// mean we reached at nearest prime
if (primes[mid] < n && primes[mid+1] > n)
return primes[mid];
if (n < primes[mid])
return binarySearch(left, mid-1, n);
else
return binarySearch(mid+1, right, n);
}
return 0;
}
// Driver program to run the case
int main()
{
Sieve();
int n = 17;
cout << binarySearch(0, primes.size()-1, n);
return 0;
}
Java
// Java program to find the nearest prime to n.
import java.util.*;
class GFG
{
static int MAX=1000000;
// array to store all primes less than 10^6
static ArrayList primes = new ArrayList();
// Utility function of Sieve of Sundaram
static void Sieve()
{
int n = MAX;
// In general Sieve of Sundaram, produces primes
// smaller than (2*x + 2) for a number given
// number x
int nNew = (int)Math.sqrt(n);
// This array is used to separate numbers of the
// form i+j+2ij from others where 1 <= i <= j
int[] marked = new int[n / 2 + 500];
// eliminate indexes which does not produce primes
for (int i = 1; i <= (nNew - 1) / 2; i++)
for (int j = (i * (i + 1)) << 1;
j <= n / 2; j = j + 2 * i + 1)
marked[j] = 1;
// Since 2 is a prime number
primes.add(2);
// Remaining primes are of the form 2*i + 1 such
// that marked[i] is false.
for (int i = 1; i <= n / 2; i++)
if (marked[i] == 0)
primes.add(2 * i + 1);
}
// modified binary search to find nearest prime less than N
static int binarySearch(int left,int right,int n)
{
if (left <= right)
{
int mid = (left + right) / 2;
// base condition is, if we are reaching at left
// corner or right corner of primes[] array then
// return that corner element because before or
// after that we don't have any prime number in
// primes array
if (mid == 0 || mid == primes.size() - 1)
return primes.get(mid);
// now if n is itself a prime so it will be present
// in primes array and here we have to find nearest
// prime less than n so we will return primes[mid-1]
if (primes.get(mid) == n)
return primes.get(mid - 1);
// now if primes[mid]n that
// mean we reached at nearest prime
if (primes.get(mid) < n && primes.get(mid + 1) > n)
return primes.get(mid);
if (n < primes.get(mid))
return binarySearch(left, mid - 1, n);
else
return binarySearch(mid + 1, right, n);
}
return 0;
}
// Driver code
public static void main (String[] args)
{
Sieve();
int n = 17;
System.out.println(binarySearch(0,
primes.size() - 1, n));
}
}
// This code is contributed by mits
Python3
# Python3 program to find the nearest
# prime to n.
import math
MAX = 10000;
# array to store all primes less
# than 10^6
primes = [];
# Utility function of Sieve of Sundaram
def Sieve():
n = MAX;
# In general Sieve of Sundaram, produces
# primes smaller than (2*x + 2) for a
# number given number x
nNew = int(math.sqrt(n));
# This array is used to separate numbers
# of the form i+j+2ij from others where
# 1 <= i <= j
marked = [0] * (int(n / 2 + 500));
# eliminate indexes which does not
# produce primes
for i in range(1, int((nNew - 1) / 2) + 1):
for j in range(((i * (i + 1)) << 1),
(int(n / 2) + 1), (2 * i + 1)):
marked[j] = 1;
# Since 2 is a prime number
primes.append(2);
# Remaining primes are of the form
# 2*i + 1 such that marked[i] is false.
for i in range(1, int(n / 2) + 1):
if (marked[i] == 0):
primes.append(2 * i + 1);
# modified binary search to find nearest
# prime less than N
def binarySearch(left, right, n):
if (left <= right):
mid = int((left + right) / 2);
# base condition is, if we are reaching
# at left corner or right corner of
# primes[] array then return that corner
# element because before or after that
# we don't have any prime number in
# primes array
if (mid == 0 or mid == len(primes) - 1):
return primes[mid];
# now if n is itself a prime so it will
# be present in primes array and here
# we have to find nearest prime less than
# n so we will return primes[mid-1]
if (primes[mid] == n):
return primes[mid - 1];
# now if primes[mid]n
# that means we reached at nearest prime
if (primes[mid] < n and primes[mid + 1] > n):
return primes[mid];
if (n < primes[mid]):
return binarySearch(left, mid - 1, n);
else:
return binarySearch(mid + 1, right, n);
return 0;
# Driver Code
Sieve();
n = 17;
print(binarySearch(0, len(primes) - 1, n));
# This code is contributed by chandan_jnu
C#
// C# program to find the nearest prime to n.
using System;
using System.Collections;
class GFG
{
static int MAX = 1000000;
// array to store all primes less than 10^6
static ArrayList primes = new ArrayList();
// Utility function of Sieve of Sundaram
static void Sieve()
{
int n = MAX;
// In general Sieve of Sundaram, produces
// primes smaller than (2*x + 2) for a
// number given number x
int nNew = (int)Math.Sqrt(n);
// This array is used to separate numbers of the
// form i+j+2ij from others where 1 <= i <= j
int[] marked = new int[n / 2 + 500];
// eliminate indexes which does not produce primes
for (int i = 1; i <= (nNew - 1) / 2; i++)
for (int j = (i * (i + 1)) << 1;
j <= n / 2; j = j + 2 * i + 1)
marked[j] = 1;
// Since 2 is a prime number
primes.Add(2);
// Remaining primes are of the form 2*i + 1
// such that marked[i] is false.
for (int i = 1; i <= n / 2; i++)
if (marked[i] == 0)
primes.Add(2 * i + 1);
}
// modified binary search to find
// nearest prime less than N
static int binarySearch(int left, int right, int n)
{
if (left <= right)
{
int mid = (left + right) / 2;
// base condition is, if we are reaching at left
// corner or right corner of primes[] array then
// return that corner element because before or
// after that we don't have any prime number in
// primes array
if (mid == 0 || mid == primes.Count - 1)
return (int)primes[mid];
// now if n is itself a prime so it will be
// present in primes array and here we have
// to find nearest prime less than n so we
// will return primes[mid-1]
if ((int)primes[mid] == n)
return (int)primes[mid - 1];
// now if primes[mid]n
// that mean we reached at nearest prime
if ((int)primes[mid] < n &&
(int)primes[mid + 1] > n)
return (int)primes[mid];
if (n < (int)primes[mid])
return binarySearch(left, mid - 1, n);
else
return binarySearch(mid + 1, right, n);
}
return 0;
}
// Driver code
static void Main()
{
Sieve();
int n = 17;
Console.WriteLine(binarySearch(0,
primes.Count - 1, n));
}
}
// This code is contributed by chandan_jnu
PHP
n
// that means we reached at nearest prime
if ($primes[$mid] < $n && $primes[$mid + 1] > $n)
return $primes[$mid];
if ($n < $primes[$mid])
return binarySearch($left, $mid - 1, $n);
else
return binarySearch($mid + 1, $right, $n);
}
return 0;
}
// Driver Code
Sieve();
$n = 17;
echo binarySearch(0, count($primes) - 1, $n);
// This code is contributed by chandan_jnu
?>
输出:
13
如果您有其他方法可以解决此问题,请分享评论。