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