This Java code prints out prime numbers between 2-100.
And this works fine.
This code is not done by me.
But I am trying to figure out what is happening with this code.
Can anyone tell me what is happening after the second (for) loop?
class primenumbers{
public static void main(String args[])
{
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
// see if the number is evenly divisible
for(j=2; j <= i/j; j++)
// if it is, then its not prime
if((i%j) == 0) isprime = false;
if(isprime)
System.out.println(i + " is prime.");
}
}
}
The first loop just for generating numbers from 2 to 100.
The second loop tries to find if the number is divisible by any other number. Here we try to divide a the number with a set of numbers (2 to prime_index).
Let's say the number is 10, the prime index is 10/2 = 5 for first iteration(j = 2). Which means, if the number 10 is not divisible by any number between 2 and 5, it's a prime number. It's divisible by 2 itself making it a non prime number.
Let's say the number is 9, now the prime index is 9/2 = 4 for first iteration(j = 2). Now, 9 % 2 gives 1 as reminder. So, loop continues for second iteration (j = 3). Now the prime index is 9/3 = 3 (Note here the prime index value is reduced from 4 to 3) So, now if the number is not divisible by 3, its decided as a prime number.
So, for every iteration, the prime index will reduce, making the number of iterations reduced.
Example for Number 97,
j = 2, prime index = 97/2 = 48 (no of iterations for loop)
j = 3, prime index = 97/3 = 32 (no of iterations for loop)
j = 4, prime index = 97/4 = 24 (no of iterations for loop)
j = 5, prime index = 97/5 = 19 (no of iterations for loop)
j = 6, prime index = 97/6 = 16 (no of iterations for loop)
j = 7, prime index = 97/7 = 13 (no of iterations for loop)
j = 8, prime index = 97/8 = 12 (no of iterations for loop)
j = 9, prime index = 97/9 = 10 (no of iterations for loop)
j = 10, prime index = 97/10 = 9 (loop exits as condition failed 10 <= 9 and declares 97 as a prime number)
Now, here the loop actually took 10 iterations instead of the proposed 48 iterations.
Let's modify the code for better understanding.
public static void main(String args[]) {
// Number from 2 to 100
for(int i=2; i < 100; i++) {
if (isPrimeNumber(i)) {
System.out.println(i + " is prime");
}
}
}
Now, lets see a method isPrimeNumberNotOptimized() which is not optimized.
private static boolean isPrimeNumberNotOptimized(int i) {
for(int j=2; j <= i/2; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
And, another method isPrimeNumberOptimized() which is optimized with prime index.
private static boolean isPrimeNumberOptimized(int i) {
for(int j=2; j <= i/j; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
Now, both methods will run and print the prime numbers correctly.
But, the optimized method will decide 97 is a prime number at 10th iteration.
And, the non-optimized method will decide the same in 48th iteration.
Hope, you understand it now.
FYI: prime index is the number we used for calculation. Such that if a number is not divisible between 2 & the derived prime index, its a prime number
This is a modification of the Sieve of Eratosthenes.
First, I'll just summarize what the sieve of Eratosthenes does, you can skip to the last paragraph if you already know this. The sieve of Eratosthenes algorithm loops through a certain boundary of numbers. (Say 2 - 100). For every number it loops through, it cancels out multiples, for example, since 2 is a prime number (true), all multiples of 2 are not (They are false). Same for 3, 5, and so on; and the algorithm skips every predetermined non-prime number. Therefore, a simulation of the algorithm would be:
2 ---prime number... cancels out 4, 6, 8, 10, 12....
3 ---prime number... cancels out 6, 9, 12, 15, 18...
4 --- ALREADY CANCELLED OUT... Skip
5 --- prime number... cancels out 10, 15, 20, 25...
6 --- ALREADY CANCELLED OUT... Skip
The numbers not cancelled are therefore the prime numbers. You can also read this for more information: http://www.geeksforgeeks.org/sieve-of-eratosthenes/
Now, to your question, your algorithm loops through the list of numbers. For each number(say x), it checks if any of the previous numbers looped through (i / j) is a factor of the x. The reason why i/j is used as the boundary for the second for loop is for efficiency. If you're checking if 10 (for example) is a prime number, there's no need to check whether 6 is a factor. You can conveniently stop at n/(n/2). That's what that part is trying to achieve.
Outer (first) loop enumerates all numbers in [2,100).
Inner (second) loop checks if a current number from the first loop is dividable by anything.
This check is done using % (remainder): (i%j)==0 when remainder of division i by j is 0. By definition when remainder is zero i is dividable by j and therefore is not a prime : isprime=false.
You only need to check in [2,i/j] because you only need to check up to sqrt(i) (explanation in the last section).
Having said that the inner loop can be re-written as:
...
int s = sqrt(i);
for(j=2; j <= s; j++)
...
however sqrt is more expensive than division, therefore it's better to rewrite j<=sqrt(i) as (squaring both sides) j^2 < i and j*j<i and j<i/j. When j is big enough j*j might overflow therefore both sides were divided by j in the final step.
Explanation of sqrt(i) taken from here: Why do we check up to the square root of a prime number to determine if it is prime?
if i is not prime, then some x exists so that i = x * j. If both x and j are greater than sqrt(i) then x*j would be greater than i.
Therefore at least one of those factors (x or j) must be less than or equal to the square root of i, and to check if i is prime, we only need to test for factors less than or equal to the square root.
public class PrimeNumber {
//check prime number
public static boolean prime(int number){
boolean isPrime=true;
for(int i=number-1;i>1;i--){
if(number%i==0){
isPrime=false;
System.out.println(i);
break;
}
}
return isPrime;
}
public static boolean getPrimeUsingWhile(int number){
boolean isPrime=true;
Integer temp=number-1;
while (temp>1){
if(number%temp==0){
isPrime=false;
break;
}
temp--;
}
return isPrime;
}
//print primenumber given length
public static List<Integer> prinPrimeList(){
boolean isPrime=true;
List<Integer> list=new ArrayList<>();
int temp=2;
while (list.size()<10){
for(int i=2;i<temp;i++){
if(temp%i==0){
isPrime=false;
break;
}else{
isPrime=true;
}
}
if(isPrime){list.add(temp);}
temp++;
}
return list;
}
public static void main(String arg[]){
System.out.println(prime(3));
System.out.println(getPrimeUsingWhile(5));
System.out.println(Arrays.toString(prinPrimeList().toArray()));
}
}
Related
The problem is to check a random number n can be the sum of 2 random prime numbers. For example,
if n=34 the possibilities can be (3+31), (5+29), (17+17)...
So far I have managed to save prime numbers to the array, but have no clue how I could check, if n is the sum of 2 prime numbers.
This is part of my code:
public static void primeNumbers(int n) {
int i = 0, candidate = 2, countArray = 0, countPrime = 0;
boolean flag = true;
while (candidate <= n) {
flag = true;
for (i = 2; i < candidate; i++) {
if ((candidate % i) == 0) {
flag = false;
break;
}
}
if (flag) {
countPrime++;
}
candidate++;
}
int[] primeNumbers = new int[countPrime];
while (candidate <= n) {
flag = true;
for (i = 2; i < candidate; i++) {
if ((candidate % i) == 0) {
flag = false;
break;
}
}
if (flag) {
primeNumbers[countArray] = candidate;
}
candidate++;
countArray++;
}
for (i = 0; i <= primeNumbers.length; i++) {
}
}
First I counted how many prime numbers are between 1-n so I can declare and initialize my array for prime numbers. Then I save prime numbers to the array. But now I have no idea how I could check if n is the sum of 2 prime numbers.
Given that you already have list of "prime numbers less than the given number", It is a very easy task to check if two prime numbers can sum to given number.
for(int i=0; i<array.length; i++){
int firstNum = array[i];
int secondNum = givenNum - firstNum;
/* Now if it is possible to sum up two prime nums to result into given num, secondNum should also be prime and be inside array */
if(ArrayUtils.contains(array, secondNum)){
System.out.println("Yes, it is possible. Numbers are "+ firstNum + " and " + secondNum);
}
}
EDIT: ArrayUtils is part of Apache Commons Lang library
You can however use ArrayList instead to use contains method.
You do not have to check all prime numbers from 1 to the given number or you don't even need an array.
Algorithm one can be;
First of all write a function that checks whether a given number is prime.
Split the number into two parts, 0 and the remaining value(the number itself). Now start decreasing the number part by 1 and start adding 1 to 0 simultaneously. Stop when the number part which we are decreasing becomes 0 or both the parts are prime numbers.
Another algorithm can be like this;(It is similar to the accepted answer)
Start subtracting prime numbers from the given number starting from 2.Check whether the subtraction is also prime.
The time you get the subtraction as a prime number, stop , you have got the two prime numbers that sum up to the given number.
I don't understand this 'for' loop in Java
This loop is just to check if a number is prime or not. I understand the first statement because 1 is not a prime number but it's what happens in the 'for' statement. Why is 'primeNumber' being divided by two and why is the second 'if' calculating for a remainder of zero? how does this code help to confirm a prime number? what is it doing?
public static boolean isPrime (int primeNumber) {
if (primeNumber == 1) {
return false;
}
for (int primeDivider=2; primeDivider <= primeNumber/2; primeDivider++) {
if (primeNumber % primeDivider == 0) {
return false;
}
}
return true;
}
A prime number can only be divided by itself and one. 7 is prime because only 1 and 7 divide into 7. Also 8 is not prime because as well as 1 and 8, both 2 and 4 divide into 8.
Look at the for loop and see what values primeDivider takes: 2, 3, 4, 5, ... The loop tries each of these in turn to see if it divides into the number you are testing. If it divides evenly, with a remainder 0, then the number being tested is not prime and the method returns false. If none of the numbers divide, then the number being tested in prime and the method returns true. As an aside, primeNumber is a bad variable name. Something like possiblePrime would be better. The number being tested might not be prime.
The primeDivider sequence stops at half the number being tested. If a number is not prime (a composite number) then at least one of its divisors is guaranteed to be less than or equal to half the number.
As others have said, this is not a very efficient test. Here is a slightly more efficient version for you to study:
public static boolean isPrime (int possiblePrime) {
// Test negatives, zero and 1.
if (possiblePrime <= 1) {
return false;
}
// Test even numbers
if (possiblePrime % 2 == 0) {
// 2 is the only even prime.
return possiblePrime == 2;
}
// Test odd numbers >= 3.
int limit = possiblePrime / 2;
for (int primeDivider = 3; primeDivider <= limit; primeDivider += 2) {
if (possiblePrime % primeDivider == 0) {
return false;
}
}
// Only prime numbers reach this point.
return true;
}
By treating odd and even numbers separately, you can catch all the even numbers with a single test and by stepping primeDivider by 2 each time, roughly halve the time taken for odd numbers.
As billjamesdev says, that can be made even more efficient by using:
int limit = (int)Math.floor( Math.sqrt( possiblePrime ));
A composite number will always have a divisor, other than 1, less than or equal to its square root.
When i study from Introduction to Java programming book of Liang, i am stuck at a point. The problem is to find prime numbers efficiently.
In order to find whether n is prime or not, we must check whether n is divisible by numbers 2,3,4,...,sqrt(n) .
We can make this algorithm more efficient by checking whether n is divisible by numbers 2,3,4,...,floor(sqrt(n)).
For example, numbers between 36 and 48, their (int)(Math.sqrt(number)) is 6. But, according to the below program, for number=40, squareRoot is 7, not 6. Namely, according to the mathematical proof, we check whether 40 is prime by checking 40 is divisible by 2,3,4,5,6.
According to the below program, we check whether 40 is prime by checking 40 is divisible by 2,3,4,5,6,7. This the contradiction. I don't understand it. Help please.
Here is the algorithm implementing this problem :
import java.util.Scanner;
public class EfficientPrimeNumbers {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Find all prime numbers <= n, enter n: ");
int n = input.nextInt();
// A list to hold prime numbers
java.util.List<Integer> list =
new java.util.ArrayList<Integer>();
final int NUMBER_PER_LINE = 10; // Display 10 per line
int count = 0; // Count the number of prime numbers
int number = 2; // A number to be tested for primeness
int squareRoot = 1; // Check whether number <= squareRoot
System.out.println("The prime numbers are \n");
// Repeatedly find prime numbers
while (number <= n) {
// Assume the number is prime
boolean isPrime = true; // Is the current number prime?
if (squareRoot * squareRoot < number) squareRoot++;
// For numbers between 36 and 48, squareRoot is 7 which contradicts with the matematical proof.!!!
// ClosestPair if number is prime
for (int k = 0; k < list.size()
&& list.get(k) <= squareRoot; k++) {
if (number % list.get(k) == 0) { // If true, not prime
isPrime = false; // Set isPrime to false
break; // Exit the for loop
}
}
// Print the prime number and increase the count
if (isPrime) {
count++; // Increase the count
list.add(number); // Add a new prime to the list
if (count % NUMBER_PER_LINE == 0) {
// Print the number and advance to the new line
System.out.println(number);
}
else
System.out.print(number + " ");
}
// Check if the next number is prime
number++;
}
System.out.println("\n" + count +
" prime(s) less than or equal to " + n);
}
}
The program only checks for divisibility by primes lower than or equal to sqrt(number) + 1. Once a prime number is detected, it gets added to your list object:
if (isPrime) {
count++; // Increase the count
list.add(number); // Add a new prime to the list
Here is where you check for divisibility by numbers in this list:
for (int k = 0; k < list.size() && list.get(k) <= squareRoot; k++) {
if (number % list.get(k) == 0) { // If true, not prime
So for numbers between 36 and 48, it checks 2, 3, 5, 7, which is actually better than 2, 3, 4, 5, 6. Asymptotically, they're still the same, but in practice, you save some work by only checking for divisibility against the primes.
In fact you can save an operation and change the <= in list.get(k) <= squareRoot to <, for the reasons you describe. Then it won't even bother with 7 for numbers between 36 and 48, and it will be closer to the theory you have.
I am a novice, please excuse my lack of organization.
Okay, so what I did was I made an array filled with all the prime numbers between 8 and 100. What I want to do now is make another array that finds all the prime numbers between 101-200. So allow me to explain how I did the first part:
//Prime1 is an dynamic integer array which stores all the prime numbers between 8 and 100
int arrayCounter = 0;
for(int primeTest = 8; primeTest<=100; primeTest++)
{
if(primeTest%2!=0 && primeTest%3!=0 && primeTest%5!=0 && primeTest%7!=0)
{
Prime1.add(primeTest); //adds the prime numbers to array
arrayCounter = arrayCounter +1;
}
else
{
arrayCounter = arrayCounter + 1;
}
}
Now back to the main issue, rather than writing "if(primeTest % "prime#" !=0)" I would like to be able to use modulus through the entire Prime1 array and see if all the values do not equal zero... Let me elaborate.
for(int primeTest2 = 101; primeTest2 <= 200; primeTest2++)
{
for(int arrayCounter2 = 0; arrayCounter2 < Prime1.size(); arrayCounter2++)
{
if(primeTest2 % Prime1.get(arrayCounter2) != 0 )
{
Prime2.add(primeTest2);
}
}
}
//please forgive any missing braces
^^So what happens here is that I take a value starting at 101 and modulus it with the first value of the Prime1 array. As you know, this may give me a false positive because 11 (the first prime number in the array) may still show true even with numbers which are not prime. This is why I need to be able to test a number with all the values in the array to ensure that it cannot be divided by any other prime number (meaning that it is prime).
Your method is extremely inefficient, nevertheless, here is how you can fix it:
for (int primeTest2 = 101; primeTest2 <= 200; primeTest2++)
{
boolean prime = true;
for (int arrayCounter2 = 0; arrayCounter2 < Prime1.size(); arrayCounter2++)
{
if (primeTest2 % Prime1.get(arrayCounter2) == 0)
{
prime = false;
break;
}
}
if (prime)
Prime2.add(primeTest2);
}
BTW, for the first set of prime numbers, it is sufficient to use 2, 3, 5, 7, 11, 13.
Take a boolean and set it to true. If the number can be divided by any of your primes from 8 to 100 without a remainder, than set it to false. If it is still true after testing every number, add the tested number to the Prime2 array, otherwise continue with the next number. Example:
for(int n = 101; n <= 200; n++)
{
boolean isPrime = true;
for(Integer p : Prime1)
if(n % p == 0 )
{
isPrime = false;
break;
}
if(isPrime)
Prime2.add(n);
}
But there are better alorithms out there to check if a number is prime or to calculate alle primes below n. For example the Sieve of Eratosthenes.
I am trying to make a prime number list. I have coded it, but it only tells me that the prime numbers of 1 - 100 is 1. I am not sure why that is happening. I also want to make a JFrame for it.
import javax.swing.JOptionPane;
public class ProgrammingAssignment7 {
public static void main(String[] args) {
//Scanner Scan = new Scanner (System.in);
//DECLARE VARIABLES
int x = 1;
int i = 1;
int iNumber = 1;
boolean bNotPrime = false;
boolean bIsPrime = true;
int iNumberToTest;
int iPrimeCheck;
int iCounter;
int iResult = 1;
int iFact = 1;
int iLimit = 100;
String OutputStr = null;
System.out.println("Prime numbers between 1 and " + iLimit);
//loop through the numbers one by one
for(i=1; i < 100; i++) {
bIsPrime = true;
//check to see if the number is prime
for(int j = 2; j < i ; j++) {
if(i % j == 0) {
bIsPrime = false;
break;
}
}
}
// print the number
if(bIsPrime) {
OutputStr = "The Prime Numbers of 1 - 100 are: " + i + "\n";
}
JOptionPane.showMessageDialog(null, OutputStr, "PRIME NUMBERS", JOptionPane.INFORMATION_MESSAGE);
//System.out.print(i + "\n" );
System.exit(0);
}
}
You are calling system.exit(0) in your for loop. So that it will terminate the program after the first iteration. Remove that line and then try to run program. It will give you correct results.
Besides fixing your code you should also fix your algorithm. You are using an algorithm called trial division, which will be uncomfortably slow as your limit increases. Instead, you should use an algorithm called the Sieve of Eratosthenes, invented over two thousand years ago and still widely used today. Here is pseudocode for a simple version of the Sieve of Eratosthenes; I'll leave it to you to translate to Java:
function primes(n)
sieve := makeArray(2..n, True)
for p from 2 to n step 1
if sieve[p]
output p
for i from p * p to n step p
sieve[i] := False
Eratosthenes' algorithm begins by making a list of numbers form 2 to the maximum desired prime n, then enters an iterative phase. At each step, the smallest uncrossed number that hasn't yet been considered is identified, and all multiples of that number, starting from its square, are crossed out; this is repeated until no uncrossed numbers remain unconsidered. All the numbers that remain uncrossed are prime. The inner loop starts at p * p because any smaller composites must have already been crossed out by smaller primes.
For example, to find the primes less than thirty, first report that 2 is prime and cross out 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26 and 28. Then 3 is uncrossed, so report it as prime and cross out 9, 12, 15, 18, 21, 24, and 27. Since 4 has been crossed out, the next uncrossed number is 5, so report it as prime and cross out 25. Finally, since 7 * 7 is greater than 30, the inner loop stops executing and the outer loop collects the rest of the primes: 7, 11, 13, 17, 19, 23 and 29.
If you're interested in programming with prime numbers, I modestly recommend an essay at my blog, which among other things provides an optimized version of the Sieve of Eratosthenes.
In the inner loop, it is enough to iterate to the SQRT(N) instead of N. It can reduces a runtime a bit.
for(int j = 2; j < Math.sqrt(i) ; j++) {
}
Smart algorithm for writing out prime numbers from 1-100 (and also 1- [how many you want] - if you change 100 for another number). Prime numbers can be divisible only by two numbers: 1 and itself, so k have to be equals or less than 2.
for (int i=1; i<=100; i++) {
int k = 0;
for (int j=1; j<=i; j++ ) {
if (i % j == 0) {
k++;
}
}
if (k <= 2) {
System.out.println(i);
}
}