I have the following code to print all prime numbers from 2 to 100:
int number1 = 2, number2 = 100, temp = 0;
System.out.println("prime numbers between" + number1 + "and" + number2 + "are :");
for (int i = number1; i <= number2; i++) {
for (int j = 2; j <= i / 2; j++) {
if (i % j == 0) {
temp = 1;
break;
} else {
temp = 0;
}
}
if (temp == 0) {
System.out.println(i);
}
}
What is the role of temp = 0 in the very beginning?
If I modify it to, lets say 1, I get a different output. The code then prints all primes starting from 5 instead of 2. Why are the other numbers skipped?
Explanation
Have a close look at your loop logic flow:
for (int i = number1; i <= number2; i++) {
for (int j = 2; j <= i / 2; j++) {
if (i % j == 0) {
temp = 1;
break;
} else {
temp=0;
}
}
if (temp == 0) {
System.out.println(i);
}
}
i starts as 2 and increments. The inner loop is:
for (int j = 2; j <= i / 2; j++) {
Inner loop is skipped
That means that for the first iterations of the outer loop, for example i = 2 the condition of the inner loop evaluates to:
j <= i / 2
// which is
2 <= 2 / 2
// which is
2 <= 1
Hence the inner loop does not even enter at all and is skipped. So we directly reach
if (temp == 0) {
System.out.println(i);
}
The same is true for the iterations, i = 3.
i = 4 is the first iteration that actually enters the inner loop and starts overwriting temp with either 0 or 1.
Meaning of temp == 0
So during the first iterations of the outer loop (i = 2, i = 3), the initial state of temp plays a role, since it determines whether i will be printed or not.
So you need it to start as 0 to have the first values, for which the inner loop is not even entered, included in the output.
Notes
That said, using temp in such a way is overly complicated. It would be better if it would be moved to the place where it is actually needed, inside the loop, given a better name and also changed to a boolean. All in all, you may simplify the code as follows:
int min = 2;
int max = 100;
System.out.println("prime numbers between" + min + "and" + max + "are :");
for (int i = min; i <= max; i++) {
boolean isPrime = true;
for (int j = 2; j <= i / 2; j++) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
System.out.println(i);
}
}
And if you are willing to introduce a helper method like:
public static boolean isPrime(int candidate) {
for (int i = 2; i <= candidate / 2; i++) {
if (candidate % i == 0) {
return false;
}
}
return true;
}
Your code will heavily simplify and be very easy to read:
int min = 2;
int max = 100;
System.out.println("prime numbers between" + min + "and" + max + "are :");
for (int i = min; i <= max; i++) {
if (isPrime(i)) {
System.out.println(i);
}
}
you need to understand, what is the role of the variable temp in this code.
The variable temp is behaving like a flag, means whenever the number found to be divisible by another number, temp variable is setting as 1 and the code stops checking.
if we scan all the number upto i/2 and the variable temp is still 0, means we didn't find any number j which can divide current number i, then the current number is prime.
edit:
the role of temp=0 at the very beginning assumes all the number is prime. if found later number is divisible then we are assigning temp=1 and we get to know that the number is not prime.
The role in temp is to simply indicate if a prime was or was not found. Then use that value to control printing of the value under test. But it is not really needed (and as already stated in the comments, should have been a boolean).
Here is one way you could improve your effort without using that value.
Other than dividing by already found primes, you can make it somewhat more efficient by doing the following:
If the first prime is even, check to make certain it isn't 2.
if it is, print it.
if even, increment number1 by 1 to make it odd.
then starting iterating by both candidates and divisors by two to get just the odd numbers.
don't divide by any number > the square root of the candidate. Otherwise you are wasting time. Example, if 97 is not divisible by any of 3,5,7,11 then it must be a prime because any larger divisor would return a quotient < 11 which has already been checked.
you don't need a temp value. Just continue to the outer loop if the number is divided. Otherwise, print the number.
int number1 = 2, number2 = 100;
System.out.println("prime numbers between" + number1 + "and"
+ number2 + "are :");
if (number1 % 2 == 0) {
if (number1 == 2) {
System.out.println(2);
}
number1++;
}
outer:
for (int i = number1; i <= number2; i += 2) {
int max = (int)Math.sqrt(i);
for (int j = 3; j <= max; j += 2) {
if (i % j == 0) {
// try next candidate
continue outer;
}
}
// must be a prime so print it.
System.out.println(i);
}
A better approach is to use the Sieve of Erastosthenes. A BitSet is perfect for this. The idea is to:
mark every bit that is not a prime.
This eliminates composite numbers since it eliminates all their prime factors from the composite positions in the bitset.
The unset bit positions in the bitset are then primes.
as the list is being built, the first unset (clear) bit in the list is as prime.
BitSet bits = new BitSet();
bits.set(0,2); // set bits 0 and 1
initialize nextBit to the first prime
int nextBit = 2; // essentially bitSet.nextClearBit(0);
Continue the loop while the next bit is less than the square root of the terminal value.
while (nextBit <= Math.sqrt(number2)) {
// mark every prime position after this one.
for (int i = 2*nextBit; i < number2; i += nextBit) {
bits.set(i);
}
// the next clear bit after the previous prime must be a prime
// since it is next unset bit
nextBit = bits.nextClearBit(nextBit+1);
}
Now display them
// This is done by simply printing all the bit positions
// that are clear up to the terminal value.
int i = bits.nextClearBit(0);
while (i < number2) {
System.out.println(i);
i = bits.nextClearBit(i+1);
}
Related
I'm new to java/programming in general and this is a homework assignment. This is what I have so far: When I run it I get the powers of 2 below the n input. example if n = 50, output is 2 + 4 + 8 + 16 + 32 + = -2
I would like the + after 32 to be gone and I don't know how to properly sum it. I would want the sum to = 62 in this case. I tried using string builder to take off the last two characters but that isn't working for me.
import java.util.Scanner;
public class Powers {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n;
System.out.print("Enter the upper limit: ");
n = scan.nextInt();
int sum = 0;
int power = 1;
for (int i = 0; i <= n; i++) {
power = 2 * power;
if (power < n && 0 < power) {
System.out.print(power + " + ");
}
sum = sum + power;
}
System.out.println(" = " + sum);
}
}
There are multiple issues here:
When reaching the upper limit you simply stop doing the output but continue doing the summation.
You use the upper limit as the number of iterations, so in case of 50 in your example, you do a sum of all values between 1 and 2^50, which is the reason why the result is negative, because the sum became larger than the maximum number an int can keep.
Concerning your question how to break a loop, there is break ;-)
Your print is always outputting a + which is why you have the + = in your output. Change the output to something like this:
if (power < n && 0 < power) {
if (i != 0) {
System.out.print(" + ");
}
System.out.print(power);
}
I've added some functionality to your code.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("Type number:");
Scanner scanner = new Scanner(System.in);
int n = 0;
while (n == 0) { // to ask again if "n" is zero.
n = scanner.nextInt();
}
if (n != 0) {
scanner.close(); // to prevent resource leak
int sum = 0;
int power = 1;
for (int i = 0; i < n; i++) {
power *= 2;
sum += power;
System.out.print(power + " ");
if (sum + power * 2 < 0 | i == n - 1) {
// Should we step to the next iteration?
// If next "sum" will be bigger than the max value for
// integers
// or if this iteration is the last - it will type "sum",
// break "for" cycle and go the next line of code after
// "for" cycle.
// So in this case System.out.print("+ "); won't be
// executed.
System.out.print("= " + sum);
break;
}
System.out.print("+ ");
}
}
}
}
public class assignment6part3 {
public static void main(String[] args) {
int q = 0;
for ( int count=1; count <= 10000; count++) {
if (Prime(count)) {
q = q + 1;
}
}
System.out.println("It comes out " + q + " times.");
}
public static boolean Prime(int n) {
if (n <= 1) {
return false;
}
for (int i = 1; i < Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
}
I'm trying to get the number of prime numbers between 0 and 10000, but when I run this, it says there are 0 prime numbers. What part of the code is causing this error?
Inside your function Prime your for loop runs like ::
for(int i = 1; i < Math.sqrt(n); i++), starting from i = 1 and every number is divisible by 1 and hence 0 prime numbers.. :P
Initialization condition for i shall be i = 2
Other things you might consider changing ::
for (int i = 1; i < Math.sqrt(n); i++) shall be changed to
for (int i = 1; i <= Math.sqrt(n); i++)
NOTE :: A more optimal way to find Primes would be https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
The code is returning false before it actually checks the numbers, because every number is divisible by 1. Also, in some cases such as 25 and 49, the factors are not less than the square root. Try this:
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
return false;
}
}
How can I find even or odd in array?
int size;
int[] myArray = new int[10];
Scanner input = new Scanner(System.in);
System.out.print("How many numbers do you enter:");
size = input.nextInt();
for(int c = 0; c < size; c++)
{
System.out.print("Enter number:");
myArray[c] = input.nextInt();
}
input.close();
for(int c = 0; c < size; c++)
{
System.out.println(myArray[c]);
}
if(size%2)
{
System.out.print("sadsadsad");
}
}
}
Use modulus operator to check if the number is even or odd. If we divide any number by 2 and reminder is 0 then the number is even, otherwise it is odd.
for(int i=0; i < numbers.length; i++){
if(numbers[i]%2 == 0)
System.out.println(numbers[i] + " is even number.");
else
System.out.println(numbers[i] + " is odd number.");
}
you can check whether a number is even or odd
if((x%2)==0)
// even
else
// odd
or
You can use the modulus operator, but that can be slow. If it's an integer, you can do:
if ( (x & 1) == 0 ) { even... } else { odd... }
here is your edited code
for(int c = 0; c < size; c++)
{
if(myArray[c]%2==0)//check num is even or odd
System.out.println(myArray[c]+" even");
else
System.out.println(myArray[c]+" even");
}
Why do you want to check with the size?
Is that you want to check that if the length of the array is odd or even?
If you want the odd and even numbers in an array, you need to check it with each element in the for loop itself.
for(int c = 0; c < size; c++)
{
if(myarray[c]%2 == 0)
{
System.out.print(myarray[c] + " is even");
}
else
{
System.out.print(myarray[c] + " is odd");
}
}
Edit
A better way to find even or odd is to check only the last number.
We know that if the last digit is divisible by 2 then it is an even else it is an odd.
So If you want to check, we just check the last digit instead of using the % operator for the whole number.
for(int c = 0; c < size; c++)
{
if(isEven(myarray[c]))
{
System.out.print(myarray[c] + " is even");
}
else
{
System.out.print(myarray[c] + " is odd");
}
}
public boolean isEven(int number)
{
return (number%10) % 2 == 0;//number % 10 gets the last digit, checks if it is divisible by 2 or not
}
This is my code for finding the sum of primes.It works good with some low numbers but if it's 2000000(2 million) it never ends.Anybody can help me?
import java.math.BigInteger;
public class Problem010{
public static void main(String[] args) {
BigInteger sum = new BigInteger("2");
//for (int i=3; i<2000000; i++) {
for(int i=3; i<10; i++){
for (int j=2; j<i; j++){
if (i % j == 0)
break;
else if (i == j+1){
sum = sum.add(BigInteger.valueOf(i));
}
}
}
System.out.println("Sum = "+sum);
}
}
your answer is 142913828922 but how?
I just changed your algorithm a little bit:
public static void main(String[] args) {
BigInteger sum = new BigInteger("2");
boolean isPrime = true;
for (int i=3; i<2000000; i++) {
double aa = Math.sqrt((double)i);
for (int j=2; j<=aa; j++){
if (i % j == 0){
isPrime = false;
break;
}
}
if(isPrime){
sum = sum.add(BigInteger.valueOf(i));
}
isPrime = true;
}
System.out.println("Sum = "+sum);
}
instead of going through all the numbers from 2 to i I just go from 2 to sqrt(i) and this improve your code running time a lot :)
#Lrrr, answer is correct. But algorithm can be further optimised. Look at my isPrime algorithm. For 2 million you don't need the BigInteger.
long sum = 2;// new BigInteger("2");
for (int i=3; i<2000000; i++) {
if(isPrime(i)) {
sum = sum + i;//.add(BigInteger.valueOf(i));
}
}
System.out.println("Sum = "+sum);
Here is isPrime method.
static boolean isPrime(int n) {
if (n < 2) {
return false;
}
if (n == 2 || n == 3) {
return true;
}
if ((n & 1) == 0 || n % 3 == 0) {
return false;
}
int sqrtN = (int) Math.sqrt(n) + 1;
for (int i = 6; i <= sqrtN; i += 6) {// loop 6 step
if (n % (i - 1) == 0 || n % (i + 1) == 0) {
return false;
}
}
return true;
}
An efficient solution could be to use Sieve of Eratosthenes to find out which number is prime below 2,000,000 (or any other number), and than post-process and sum them all:
int n = 2000000;
boolean[] isPrime = new boolean[n];
//preprocess - set up the array
for (int i = 2; i<n;i++) isPrime[i] = true;
//run sieve:
for (int i = 2; i < (int) Math.sqrt(n) + 1; i++) {
if (isPrime[i]) {
for (int j = 2; j*i < n; j++) isPrime[i*j] = false;
}
}
//sum primes:
long sum = 0;
for (int i = 2; i < n; i++) {
if (isPrime[i]) sum+=i;
}
System.out.println(sum);
As opposed to checking for each number at a time if it is prime or not (which takes O(sqrt(n)) - and by doing it for all numbers you get O(nsqrt(n)), in here you aggregate knowledge from previous iterations, effectively lowering the complexity to O(nloglog(n)), which is significantly faster for large enough values of n.
This comes at a cost of O(n) additional space.
You could use Sieve of Eratosthenes algorithm, it is more efficient then yours.
1) Store all numbers between 2 and N in array and mark them all as prime numbers.
2) Start from X = 2, and mark all its i*X (2X, 3X..), where i is natural number less then or equal N, multipliers as not prime. Do not mark X.
3) Find the next number greater then X which is not marked and repeat the procedure. If there is no such number, stop.
4) Remaining numbers in your array are prime
Something like this:
public static boolean[] findPrimes (int N) {
boolean[] primes = new boolean[N + 1];
// assume that all numbers are prime within given range
for (int i = 2; i <= N; i++) {
primes[i] = true;
}
// for all numbers in range, starting from 2
for (int i = 2; i*i <= N; i++) {
// mark natural multiples of i as nonprime
if (primes[i]) {
for (int j = i; i*j <= N; j++) {
primes[i*j] = false;
}
}
return primes;
}
5) Iterate over returned primes and sum indexes of TRUE values
I developed my own solution and it completes in 700 milliseconds to find all below 2 million.
I use the iterative method but I just stop looking for the numbers greater than (n/i)+1 where n is the number being checked if it is prime and i is the number in the iterative loop to see if it is a divisor.
public void run () {
long sumOfPrimes = 2;
int maxNumber = 2000000;
int counter = 0;
for (int i = 3; i <= maxNumber; i = i+2) {
if(isPrimeOptimized(i)){
sumOfPrimes = sumOfPrimes + i;
counter ++;
}
}
System.out.println("num of primes is " + counter);
System.out.println("sum of primes is " + sumOfPrimes);
}
private boolean isPrimeOptimized(int n){
int limitToDivide = n;
for(int i=2;i<=limitToDivide && i<n;i++){
if(n%i == 0)
return false;
else
limitToDivide = (n/i) + 1;
}
return true;
}
So far no one has actually implemented the Sieve correctly. Double check the wikipedia page and pay attention to how you are looping through the numbers. Without any optimizations using an array of int (or booleans) it should take only a few seconds in Java.
I've written the following code:
int oddProd = 1;
for(int count = 1; count >= 15; count++){
if (count % 2 != 0)
oddProd = oddProd * count;
}
System.out.println("Odd Product: " + oddProd);
Why doesn't this work? It outputs 1, and I checked, it doesn't even enter the for loop!
for(int count = 1; count >= 15; count++){
You have the expression written the wrong way around; it is now count >= 15 but it should be count <= 15.
The middle part of the for loop is the boolean check, and yours will always be false:
count >= 15;
This won't work since it won't be true in the beginning, and your loop won't start. Change the greter than operator to a less than one:
count <= 15;