// This method takes one parameter P
// to check if P is prime
public boolean isPrime(int P) {
for(int i = 2; i < P; ++i) {
if(P % i == 0) return false;
}
return true;
}
Approach 2: Whenever there is a divisor greater than square-root(P), there must be another divisor less than or equal to square-root(P) but NOT greater than square-root(P). For example: Divisors of 20 are: 20 = 1, 2, 4, 5, 10 and 20. For each of these pairs there MUST be least one divisor that is less than or equal to square-root(P).
public boolean isPrime(int P) {
// i * i <= P is similar to i <= sqrt(p)
for(int i = 2; i * i <= P; ++i) {
if(P % i == 0) return false;
}
return true;
}
Approach 3: The only prime number that is even is 2. Any other even number cannot be prime because all even numbers are divisible by 2. So, instead of dividing by all the numbers in range 0 to (P - 1) we’ll divide only by odd numbers up to sqrt(P).
public boolean isPrime(int P) {
if(P == 2) return true;
else {
for(int i = 3; i * i <= P; i = i + 2) {
if(P % i == 0) return false;
}
}
return true;
}
Approach 4: Suppose we need to find prime numbers between 1 and 25. The algorithms described above are capable of providing a result but are not optimal. We might have to divide by the same divisor over and over again. For example, we are checking if each of the dividends below are being divided by 2 and 3.
boolean[] p = new boolean[50000];
public int[] prime(int n) {
// Initially, mark all numbers as prime
for(int i = 0; i <= n; ++i)
p[i] = true;
// 0 and 1 are not prime numbers
p[0] = p[1] = false;
for(int i = 2; i * i <= n; ++i) {
if(p[i] == true) {
for(int j = i + i; j <= n; j = j + i) {
// mark multiples of i as non-prime
p[j] = false;
}
}
}
int k = 0;
// prime[] harvests prime numbers
int[] prime = new int[n/4];
for(int i = 0; i <= n; ++i) {
if(p[i] == true) {
prime[k++] = i;
}
}
return prime;
}
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (1)
Commented:
1. Instead of the for-loop condition "i*i <= n", calculate (int)sqrt((double)n), store it in an int called sqrt_n, and then use "i <= sqrt_n" -- that saves O(n) multiplications.
2. The for-loop increment step "j = j + i" is more efficiently written "j += i". In fact, since the initialization and the increment step are the same, the whole loop can be written: "for (j=i; (j+=i) <= n; )"
3. In general, unless there's a good reason, use prefix decrementation ("--i") and post-fix incrementation ("i++").
4. Why bother writing "== true"? If it's a boolean, write just "if (mybool)" rather than "if (mybool == true)"! This saves O(n) subtractions, because comparison is simply subtracting the two values, noting positive/negative/zero, and throwing out the result.
5. I've found it worthwhile, when stepping through an array from end to end, to maintain a pointer and increment it rather than use an integer as a subscript, because that involves O(n) addition operations total. For example the sieving loop in the Eratosthenes method is better written:
Open in new window
Of course the lower loop has two additions per iteration, so there are no savings there.