For loop limit endless yet still working - java

I have been doing Java for a decently long time and I stumbled across this piece of code. I don't understand how it works:
int func(int num){
int counter=0;
for(int i=5;num/i>=1;i=i*5)
counter=counter+num/i;
return counter;
}
This function is a part of the program which counts the number of trailing zeros in a factorial. What I don't understand is the for loop part. The limit is usually the second condition and out here it is "num/i>=1".
I don't understand that if i take num as 100, the limit would be 100/5 = 20? But the part ">=1" is confusing me.

In the java for loop, there is no limit. You might be thinking of BASIC.
In the java for loop, the 2nd expression is the termination expression. The loop will keep looping for as long as the termination expression is true.
(That's why I prefer to think of it as the continuation expression, but never mind me.) Ofcourse, this expression must evaluate to a boolean.
100/5 would be illegal as a termination expression, because it is of type int, not type boolean.
100/5 >= 1 is a legal termination expression. The loop will repeat for as long as num/i is larger than or equal to 1.
More information about the java for loop:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html

Your loop is equivalent (more or less) to this:
int func(int num){
int counter=0;
for(int i=5; i<=num;i=i*5)
counter=counter+num/i;
return counter;
}
for a case where num = 100
the first iteration will be i=5 and num=100
the second iteration will be i=25 and num=100
the third iteration will be i=125 and num=100 in this case the loop exists because the condition (num/i >= 1 [which is equivalent to] i<=num) is no longer fulfilled (Edit: just in case num/i = 0 in this case)

This condition instructs the loop to continue until num/i becomes one or less. This is simply a boolean condition, which may be true or false. Once the condition becomes false, the loop stops.
Since i becomes five times greater than it has been during the prior iteration, the loop effectively divides by five to the power of k+1, where k is the number of iterations.
You can rewrite this by multiplying both sides by i:
for (int i=5 ; num >= i ; i=i*5) {
counter += num/i;
}

num/i>=1 is, in fact, a condition.
Let's look at a few examples
num = 100; i = 5;
num/i >= 1; // true because 100/5 is greater than 1
num = 100; i = 200;
num/i >= 1; // false because 100/200 is not greater than 1.
As you can see, num/i >= 20 is a condition that evaluates to true or false. The only tricky thing is that there is an expression (num/i) in the condition, rather than a single number.

num/i>=1 means your loop will be executed as long as this statement is true, so as long as the result of num divided by i ist greater
The thing is, that i is your loop variable, so it will grow everytime your loop is execute. So num/i will get smaller, until it is eventually smaller than 1.
Example: Num = 50
Loop: 50/5 >= 1? --> True
Loop: 50/25 >= 1? --> True
Loop: 50/ >= 1?25 --> False
At this point your Loop will stop.

Ok let's take a simple example.
Here is the code:
public class Fact {
public static void main(String[] args) {
new Fact().func(98);
}
int func(int num) {
int counter = 0;
for (int i = 5; num / i >= 1; i = i * 5) {
System.out.println("num: "+num + "/" + i + " = " + num / i);
counter = counter + num / i;
System.out.println("Counter = " + counter);
}
return counter;
}
}
And here is the output for the example of 98.
run:
num: 98/5 = 19
Counter = 19
num: 98/25 = 3
Counter = 22
BUILD SUCCESSFUL (total time: 0 seconds)
What happens is that: num/i is evaluated for the first loop step to 98/5 = 19.6 but it is rounded by java to 19 (it is integer).

num/i>=1 is a condition. How did you conclude 20 (100/5=20) will limit for the loop. denominator i is updated by the factor of i in each loop and check the condition. So for input num = 100 this how the loop will process
First
for(i=5; 100/5>=1; i=25) condition is true
Second
for(i=25; 100/25>=1; i=125) condition is true
In third iteration condition fails since 100/125 is not >=1.
100 has 2 zero and loop iterated 2 times.

Related

Having problems understanding following simple algorithm

public class Test1
{
public static void main (String[]args)
{
int number = 0;
for (int i = 0; i < 5; i++)
{
if (number != 0)
{
number = i * number;
}
else
{
number = i;
}
}
System.out.println (number);
}
}
I'm not quite sure how this algorithm works. My thought process is:
We set number to 0 by default.
In the for loop we are just saying, continue counting i till it's no longer smaller than 5.
We say that if number isn't 0, we update number by multiplying it with i. So in our case, i is 0,1,2,3 and 4.
Else we are saying the number is i and i is what we were counting.
Lastly, we print number.
Am I missing something? Am I wrong somewhere?
If I run this code why do I get 24 as output? I cannot understand how this simple program works.
public class Test
{
public static void main (String[]args)
{
int number = 0;
for (int i = 0; i < 5; i++)
{
if (number != 0)
{
number = i * number;//For i=2, 3, 4
}
else
{
number = i;//This is executed twice - for i=0 and i=1
}
}
System.out.println (number);
}
}
Let's understand this program.
Execution begins from the main() method.
A variable named number is defined and initialized to 0.
A loop control variable named i is defined. Its initial value is 0 and it is increased by 1 at the end of every iteration till it reaches 5. Note that i is never modified inside the loop body.
For i = 0, the condition number != 0 is false, the else block is executed. number = i. The value of number remains 0.
For i = 1, the condition number != 0 is false, the else block is executed. number = i. The value of number changes to 1.
For i = 2, the condition number != 0 is true, the if block is executed. number = i * number. The value of number changes to 2.
For i = 3, the condition number != 0 is true, the if block is executed. number = i * number. The value of number changes to 6.
For i = 4, the condition number != 0 is true, the if block is executed. number = i * number. The value of number changes to 24.
Since i = 5, the loop breaks. The value of number is printed.
This is how we end up getting 24 as the output.
Executing the algorithm step by step will help understanding it.
Let's start with the first line. As you said, this line just sets number to 0.
int number = 0; | number: 0
I included the value of the variable on the right side after the bar.
Second step is to start with the loop. Before the loop starts, the counter variable i is set to zero.
int i = 0; | number: 0, i: 0
As a second step we have to check if the loop criterion is fulfilled, so that the body of the loop will be executed.
The criterion of the loop is i < 5 and since the current value of i is 0 and 0 < 5, the body of the loop is executed:
if (number != 0) {
number = i * number;
} else {
number = i;
}
Since it is an if statement, we have to see if the if-condition is fulfilled. number is currently 0, so number != 0 is not true. This means we go to the else branch with is:
number = i; | i = 0 -> number = 0
Since i is zero, number continues to be zero after this statement was executed.
This is the end of the first execution of the loop. Last thing the loop does before restarting is incrementing the counter:
i++; | number = 0, i = 1
Now i < 5 is still true, so the loop body runs again.
We still have number = 0 therefore number != 0 is still false.
Note that i was updated to 1, but number was not until now. Now:
number = i; | i = 1 -> number = 1
Now the loop increments the counter and starts anew:
i++; | i = 2
Still i < 5, so the body of the loop is executed again.
For the first time number != 0 is true, because number = 1.
So now we execute:
number = i * number; | i = 2 -> number = 2
number used to be 1, i is to, so i * number = 2
Again the loop body ends, the counter is incremented and the loop restarts, since 3 < 5:
i++; | i = 3
Here again number != 0, so we execute
number = i * number;
which yields number = 6 since 2 * 3 = 6.
The same process continues one more time with i = 4.
Now number = 4 * 6 = 24.
We increment the counter
i++; | i = 5, number = 24
Now i < 5 is no longer true, the loop exits and
System.out.println(number);
prints the current value of number, 24 to the screen.
Your thought process was good, but it wasn't exact or detailed enough because the meshing/merging of the sequence of the multiplication (of number) with the sequence of incrementing i is important.
Work it out on paper with a table, one column per variable, one line per instruction executed:
i number
null 0 int number = 0; // i has not been initialized yet.
0 0 int i = 0;
0 0 number = i; // it took the else branch
1 0 i++
1 1 number = i;
2 1 i++
2 2 number = i * number
3 2 i++
3 6 number = i * number
4 6 i++
4 24 number = i * number
5 24 i++
5 24 falls out of loop since i < 5 is now false

Postdecrement Operations in While loop

b = 5;
loopiterations = 0;
while (b-- > 0) { // Use a postfix decrement
loopiterations++;
}
System.out.println("Postfix decrement operator used, loopiterations = " +
loopiterations + ", b = " + b);
The result is
Postfix decrement operator used, loopiterations = 5, b = -1
I don't understand why the value of b is -1. The value of b starts from 5 (after while loop it's value is 4) and then ends at 1 ( after the while loop it is 0) and then the iteration from 5 to 1 is 5.If how I think is right, why is the value of b is -1 after looping. Thank you.
This block of code
while (b-- > 0) {
// do something
}
is semantically the same as
while (b > 0) {
b--;
// do something
}
b--;
The loop while (b-- > 0) exits as soon as b == 0, but because of the post decrement operation b will be one last time decrement and hence b will have the value of -1 when printing.
**postfix increment or decrement actually happens after using value**, the initial value of b is 5 so in the first iteration 5 is checked for condition after the last iteration, b becomes 0 after its value (1 at time of comparison) has been decremented, then 0 is checked but the condition is false but due to postfix decrement it's value becomes -1.
postfix -> first use value then decrement or increment that's how it works
This is because when b == 0, the postfix will return false and your while loop will terminate. However, the postifx will still subtract one from b. Therefore, the loop is executed 5 times, and iterations = 5. However, b is decremented 6 times.

Calculating how many times a number is added to itself until it reaches an arbitrary value?

Considering two variables:
"n" is any arbitrary value.
"i" is the number of times a value is increased in a sum before it reaches the value of "n".
So for instance if the value n = 344 is chosen, then i = 26 because:
26 + 25 + 24 + ... + 3 + 2 + 1 = 351
26 is how many times the variable "i" gets added together in a descending order before it either is equal to n = 344 or the first time it surpasses.
public class Trstuff{
public static void main (String [] arg) {
int n = 4;
int i = computeIndex(n);
System.out.print(i);
}
public static int computeIndex(int n) {
int i = 1;
int sum = 0;
for(i = 1; sum <= n; i++) {
sum = sum + i;
}
return i;
}
}
My goal is to choose any "n" value and then have the program return the variable "i" to me.
As my program stands, I thought it should be correct, but somehow it's not. Here is the example with n = 4.
The result should be that "i = 3" because:
1 + 2 = 3
1 + 2 + 3 = 6
So the ascending value of "i" in the loop is added 3 times before the loop supposedly should stop because of the expression "sum <= n" in the loop.
However, when I run the program it returns the value 4 instead. I simply cannot figure out what is wrong and why my program gives me 4 instead of the correct answer, 3?
Read the for loop as follows:
for every value of i while sum smaller or equal to n, add i to sum and increment i
The last part of the line and increment i is executed after the sum of sum + i, but before the next check which checks if sum is smaller or equal to n, with as result that i always is one larger than expected.
The solution could be to use a different exit (different solutions exist):
public static int computeIndex(int n) {
int i = 1;
int sum = 0;
while true {
sum = sum + i;
if sum<n {
i++;
} else break;
}
return i;
}
the sum of p consecutive integers starting at 1 is p*(p+1)/2
so basically you need to solve x^2+x-2*n = 0, with solution
x = 0.5*(sqrt(1+8n)-1)

Why does this while loop run after the condition is met?

When I do a regular while loop like this
int x = 0;
while (x < 2) {
System.out.println(x);
x = x + 1;
}
it prints
0
1
but this second while loop runs one more time after the condition is met.
class Hobbits {
String name;
public static void main(String [] args) {
Hobbits [] which = new Hobbits[3];
int number = -1;
while (number < 2) {
number = number + 1;
which[number] = new Hobbits();
which[number].name = "bilbo";
if (number == 1) {
which[number].name = "frodo";
}
if (number == 2) {
which[number].name = "sam";
}
System.out.print(which[number].name + " is a ");
System.out.println("good Hobbit name");
}
}
}
so the result is
bilbo is a good Hobbit name
frodo is a good Hobbit name
sam is a good Hobbit name
shouldn't it stop printing at "frodo is a good Hobbit name"
I set the condition for x < 2 so how does "sam" print if the while loop was supposed to stop at x == 1?
Edit: ohhh I get it now lol I was thinking like the increment was at the end of the code and the start was 0
Here's your test case more closely matching your code:
class Test {
public static void main(String[] args) {
int x = -1;
while (x < 2) {
x = x + 1;
System.out.println(x);
}
}
}
It does indeed print:
$ java Test
0
1
2
Your loop is not designed to stop when number is 2, it's designed to stop before the next iteration if the number is 2. Since you increment number early on in the loop, it will continue with that value until it's time to choose whether to iterate again.
Before the first iteration, number = -1 which is <2 so it should iterate.
Before the second iteration, number = 0, which is <2 so iterate.
Before the third iteration, number = 1, which is <2 so iterate.
Before the fourh iteration, number = 2, which is NOT <2 so stop.
You therefore get 3 iterations.
Your original test case had the right idea -- it's better to increment as the last step in the loop. That way, you start at 0 instead of -1, and you stop the loop based on the new value rather than the previous value.
I will try to trace through it for you.
First case this is what happens.
x = 0
is 0 < 2? yes
print 0
0 <- 0 + 1 // here it becomes 1
is 1 < 2? yes
print 1
1 <- 1 + 1 // here it becomes 2
is 2 < 2? no
exit program
second loop works a bit more like this
number = -1
is number < 2? yes
number <- -1 + 1 // here it becomes 0
make hobbit "bilbo" at index 0
0 does not equal either 1 or 2
print hobbit at index 0 who is "bilbo"
is 0 < 2? yes
0 <- 0 + 1 // here it becomes 1
number equals 1 so make "frodo" at index 1
print hobbit at index 1 who is "frodo"
is 1 < 2? yes
1 <- 1 + 1 // becomes 2
number equals 2 so make "sam" at index 2
print hobbit at index 2 who is "sam"
is 2 < 2? no
end program
There's nothing wrong in that behaviour. You set number = -1 and then you do a loop that will iterate while number < 2. So, -1, 0 and 1. Three iterations. What's the problem? Let's do a simple trace:
number = -1
(-1 < 2)? Yes. Execute code inside while.
number = number + 1 (0)
(0 < 2)? Yes. Execute code inside while.
number = number + 1 (1)
(1 < 2)? Yes. Execute code inside while.
number = number + 1 (2)
(2 < 2)? No. Continue with the next instruction after the while block.
you can solve this easily with replace
int number = -1;
to
int number = 0;
Because! -1 + 1 = 0;
Because you have 3 iterations that are true:
-1 < 2 == true
0 < 2 == true
1 < 2 == true
2 < 2 == false
Cheers

I have a program that calculates the first 200 prime numbers, but I do not understand a formula in it

I need to write a code which should calculate the first 200 prime numbers, but I can't hand it in as long as I can't explain everything. I used a piece of code from the internet as reference (http://crab.rutgers.edu/~dhong/cs325/chapter3/PrimeNumber.java).
Whole code:
public class Opdracht3 {
public static void main(String[] args) {
int limiet = 200;
int counter = 1;
int testpriem = 3;
boolean isPriem;
while (counter <= limiet) {
isPriem = true;
for (int i = 2; i <= testpriem / 2; i++) {
if (testpriem % i == 0) {
isPriem = false;
break;
}
}
if (isPriem) {
System.out.println(counter + ": " + testpriem);
counter++;
}
testpriem++;
}
}
}
Below part of code verifies if the number is a composite. If testpriem is composite, then comes out of the loop and starts over. Otherwise, it continues and prints the prime number testpriem.
The problem is here:
for (int i = 2; i <= testpriem / 2; i++) {
if (testpriem % i == 0) {
isPriem = false;
break;
}
}
I tested what happens to i, and one way or another it recognizes the divisor needed to calculate the composite. (With 4 divisor is 2, with 9 divisor is 3, with 221 divisor is 13) But I am flabbergasted as of why.
Any ideas?.
the % or ("remainder") operator in Java divides one operand by another and returns the remainder as its result. And of course if integer x is evenly divisible by another integer y (meaning x/y = some integer z with a remainder of zero), then x can not be prime.
First remember every number able to divide by its half or less. Consider number 7 it is possible divided by 1,2,3 because after 3, if try to divide number by 4 means 4x2 = 8 that is greater than 7. so it is optimum way to find divisor in this way. One more thing every number divided by 1 and number itself. so if number number is divided by 1 or itself then it is called prime so i starts from 2.
now consider testpriem =7 so you will get loop like
for (int i = 2; i <= 7 / 2(i.e 3); i++)
{
if(7 % i == 0)
{
isPriem = false;
break;
}
so first time it checks 7%2=1 so condition false. again check for 7%3 = 1 again condition false. and now this condition full fills here i <= 7 / 2(i.e 3) so loop stopped and it result 7 number is prime
Well, if testpriem % i == 0, it means that i divides testpriem, which means that testpriem is not a prime a number and i, is its first divider. % is the modulo operation, which is the rest of the division.
https://en.wikipedia.org/wiki/Modulo_operation
The break stops the for loop and moves to the next position in the while loop. So it does not restart the for loop for the current tested number.
The break is used for efficiency reasons. You could remove it and the algorithm would still work correctly but slower.

Categories

Resources