There are many approaches to find the primes below a specific number. few better approaches will be Sieve of Eratosthenes and Segmented Sieve (for larger limit).
Below are the Java implementation of both.
Sieve of Eratosthenes Java Implementation
/**
* @param limit : The limit can not be large as 1000,000,000
* @return List of primes up to limit, i.e. in the range [0, limit]
*/
static List< integer > simpleSieve(int limit) {
boolean mark[] = new boolean[limit];
Arrays.fill(mark, true);
for (int p = 2; p * p < limit; p++) {
// If p is not changed, then it is a prime
if (mark[p] == true) {
// Update all multiples of p
for (int i = p * 2; i < limit; i += p) {
mark[i] = false;
}
}
}
List< integer > list = new ArrayList<>();
for (int i = 2; i < limit; i++) {
if (mark[i]) {
list.add(i);
count++;
}
}
return list;
}
Segmented Sieve Java Implementation
/**
* @param n : The value n can be large
* @return List of primes up to n, i.e. in the range [0, n]
*/
static List< integer > segmentedSieve(int n) {
int limit = (int) Math.sqrt(n) + 1;
List< integer > primes = simpleSieve(limit);
List< integer > primesFinalList = new ArrayList<>();
primesFinalList.addAll(primes);
int low = 2;
int high = limit;
while (low < n) {
boolean mark[] = new boolean[limit + 1];
Arrays.fill(mark, true);
for (int i = 0; i < primes.size(); i++) {
int temp = primes.get(i);
int loLim = (int) Math.floor(low * 1.0 / temp) * temp;
if (loLim < low) {
loLim += temp;
}
for (int j = loLim; j < high; j += temp) {
mark[j - low] = false;
}
}
for (int i = low; i < high; i++) {
if (mark[i - low] == true) {
primesFinalList.add(i);
count++;
}
}
low = low + limit;
high = high + limit;
if (high >= n) {
high = n;
}
}
return primesFinalList;
}
Segmented Sieve for a Range
/**
* @param leftLimit
* @param rightLimit
* @param maxRangeCapacity
* : maximum value for (rightLimit - leftLimit)
* @return primes in the range [leftLimit, rightLimit]
*/
static List< Integer > segmentedSieveForRange(int leftLimit, int rightLimit,
int maxRangeCapacity) {
List< Integer > list = new ArrayList<>();
// max limit to consider is 1000,000,000
// sqrt(1000,000,000) <= 31623 ; so lets find all primes upto 40,000
// with a
// safe margin
boolean[] shieves = new boolean[40000];
int numberOfPrimes = 0;
// the number of primes below 40,000 is less than 4205 (can even find
// from brute force)
int[] index = new int[4205];
// mark all as true (i.e. as primes)
Arrays.fill(shieves, true);
for (int i = 2; i * i < shieves.length - 1; i++) {
if (shieves[i]) {
// Update all multiples of i. NOTE : i is a prime
for (int j = i; i * j < shieves.length; j++) {
shieves[j * i] = false;
}
}
}
// fill the index array where we store our primes below 40000
for (int i = 0; i < shieves.length; i++) {
if (shieves[i]) {
index[numberOfPrimes++] = i;
}
}
if (leftLimit < 2) {
// the smallest prime
leftLimit = 2;
}
// maxRangeCapacity = 1000,000
boolean[] isPrime = new boolean[maxRangeCapacity + 1];
Arrays.fill(isPrime, true);
for (int k = 2; k < numberOfPrimes; k++) {
int u = index[k];
int start = 0;
if (u >= leftLimit) {
start = 2 * u;
} else {
start = leftLimit + ((u - leftLimit % u) % u);
}
for (int l = start; l <= rightLimit; l += u) {
isPrime[l - leftLimit] = false;
}
}
for (int p = leftLimit; p <= rightLimit; p++) {
if (isPrime[p - leftLimit]) {
list.add(p);
}
}
return list;
}
Sample solution to the problem Twins in Hackerrank
public class TwinPrime {
public static void main(String[] args) throws NumberFormatException,
IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
System.out));
String[] temp = in.readLine().split(" ");
int x = Integer.parseInt(temp[0]);
int y = Integer.parseInt(temp[1]);
List< Integer > list = segmentedSieveForRange(x, y, 1000000);
int count = 0;
int size = list.size();
for (int i = 0; i < size - 1; i++) {
if (list.get(i + 1) - list.get(i) == 2) {
count++;
}
}
System.out.println(count);
}
/**
* @param leftLimit
* @param rightLimit
* @param maxRangeCapacity
* : maximum value for (rightLimit - leftLimit)
* @return primes in the range [leftLimit, rightLimit]
*/
static List< Integer > segmentedSieveForRange(int leftLimit, int rightLimit,
int maxRangeCapacity) {
List< Integer > list = new ArrayList<>();
// max limit to consider is 1000,000,000
// sqrt(1000,000,000) <= 31623 ; so lets find all primes upto 40,000
// with a
// safe margin
boolean[] shieves = new boolean[40000];
int numberOfPrimes = 0;
// the number of primes below 40,000 is less than 4205 (can even find
// from brute force)
int[] index = new int[4205];
// mark all as true (i.e. as primes)
Arrays.fill(shieves, true);
for (int i = 2; i * i < shieves.length - 1; i++) {
if (shieves[i]) {
// Update all multiples of i. NOTE : i is a prime
for (int j = i; i * j < shieves.length; j++) {
shieves[j * i] = false;
}
}
}
// fill the index array where we store our primes below 40000
for (int i = 0; i < shieves.length; i++) {
if (shieves[i]) {
index[numberOfPrimes++] = i;
}
}
if (leftLimit < 2) {
// the smallest prime
leftLimit = 2;
}
// maxRangeCapacity = 1000,000
boolean[] isPrime = new boolean[maxRangeCapacity + 1];
Arrays.fill(isPrime, true);
for (int k = 2; k < numberOfPrimes; k++) {
int u = index[k];
int start = 0;
if (u >= leftLimit) {
start = 2 * u;
} else {
start = leftLimit + ((u - leftLimit % u) % u);
}
for (int l = start; l <= rightLimit; l += u) {
isPrime[l - leftLimit] = false;
}
}
for (int p = leftLimit; p <= rightLimit; p++) {
if (isPrime[p - leftLimit]) {
list.add(p);
}
}
return list;
}
}

2 comments:
Useful java program. Helped in my interview. Thanks for sharing.
Cheers,
http://www.flowerbrackets.com/java-program-to-find-prime-number/
1xbet korean domain legalbet.co.kr
1xbet korean 1xbet domain legalbet.co.kr - No Deposit Bonus febcasino - 1xbet, Min deposit €10, Free No Deposit Bonus. 1xbet, Min deposit €10, Min 바카라 amount, 10.
Post a Comment