Need help understanding Java program flow - java

Code:
public static char f( char c ){
System.out.print( c++ );
return c--;
}
public static void main(String[] args)
{
if( f('j') == 'k' || f('f') == 'f'){
System.out.println( f('d') );
}
}
Can someone please explain to me why this prints "jde"??
Intuitively, I thought it would print "kged".

The value of the expression c++ is the value of c BEFORE it gets incremented. And the value of the expression c-- is the value BEFORE it gets decremented.
So in the first call to f in your example, c starts off as 'j'. Then the line System.out.println(c++); prints 'j' and increments c, so that it's now k. On the next line, it returns the new value of c, which is 'k'.
Since the first half of the if condition is true, the second half is not evaluated. We jump straight into the body of the if. But this works the same way as before - it prints 'd' and returns 'e'. The 'e' is then printed.

c++ is incremented after the System.out.print, so it prints 'j' first.
The second part of the if statement is not evaluated since f('j') returns 'k' as the decrement is applied after the return.
Then d is printed because f('d')' is called which first prints 'd' and then the result of the function 'e'.
If you want to understand why a problem is doing something, especially if it is rather unexpected, it is a good idea to get familiar with a debugger. With that you can step through every instruction, and see the state of your program at every execution step.
As an exercise, write a program which is using those functions, but prints qed (quod erat demonstrandum).

In the if condition is f('j')=='k' which is true and that is why other condition is not being checked. Here f('j') methods prints j and returns 'k' and after returning c is again 'j'. Now in System.out.println(f('d')); f('d') prints d and returns e which is printing in main method. So the output is jde

Related

Boolean logical operators for flow controls in java

Can't we use Boolean logical operators (such as &,|,!,^ etc) in java flow controls ( for loop,while loop etc) ???
I want to print all even numbers between 1 and 100.So I used below two source codes.
import java.util.*;
class Example{
public static void main(String args[]){
int i=1;
while(i<100){
if(i%2==0)
System.out.print(i+" ");
i++;
}
}
}
This code is compiled and prints all even numbers between 1 and 100.
import java.util.*;
class Example{
public static void main(String args[]){
int i=1;
while(i<100 & i%2==0){
System.out.print(i+" ");
i++;
}
}
}
This code is compiled without any error.but doesn't give any print.
Why is that ?
Can't we use Boolean logical operators within a while loop ?
Remember that the while loop condition is the condition to continue the loop, which means that when the condition is false, the loop stops.
If you negate the condition in the second code:
!(i<100 & i%2==0)
Using De Morgan's Law, This is equivalent to:
i>=100 | i%2!=0
Or in words:
i is greater than or equal to 100 OR i is odd.
This is the stopping condition of the while loop. Well, i is initially 1, which is odd, so the loop stops without even executing one iteration.
In other words, you can't rewrite the first code as the second code. They are not equivalent. What goes in the if condition goes in the if condition. You can't "merge" it into the while condition, because they are for different purposes.
I also recommend && for the logical AND, as it only evaluates the right operand when necessary. For more info, see What is the difference between & and && in Java?
The error is in this line:
while(i<100 & i%2==0){
& should be replaced with &&:
while(i<100 && i%2==0){
U have tearn the logical operators...
and it is a logical operator it can be true only if 2 operators are true( x>5 and y<7) will be true if only x>5 is true and y<7 is true that is give us the condition is true but if one of them is not verified the condition is false....
but if we have or operator the condition will be true only if one of them is true or both........
so let's explain ur code.
You have condition (i<100 and i%2==0).
0%2 ==0 so it is true and of course i<100 so while returns true(both true at the same time) but when i==1 here we have a problem 1%2!=0 so i<100 is true but i%2==0 is false so we get **true && false ** the result is false .
(true && true==true) (false && true==false) (false and false==false) (true ||true==true) (true || false==true) (false||false==false)

Recursion gives unexpected/wrong output?

So I was doing a recursion challenge on codingbat and came across the "bunny ears" problem where we have a number of bunnies and each bunny has two big floppy ears. We want to compute the total number of ears across all the bunnies recursively (without loops or multiplication).
The solution apparently is quite simple:
public int bunnyEars(int bunnies)
{
if(bunnies == 0)
return 0;
return 2+bunnyEars(bunnies-1);
}
But I am not able to understand. If we pass 2 in the bunnyEars(2) method the
recursive part bunnyEars(bunnies-1); should have 1 left in the bracket after subtraction and thus 2+(1); which should be equal to 3 and not 4.
But the output comes as 4. So how does recursion actually work in this code?
It is not 2+(1), it is 2+numberOfEarsOfBunnies(1) == 2+2.
I renamed the function a little to make it more obvious.
Or even more into detail:
numberOfEarsOfBunnies(2)==
2+numberOfEarsOfBunnies(1)==
2+(2+numberOfEarsOfBunnies(0))==
2+(2+0)==
2+2==
4
if we pass 2 in the bunnyEars(2) method the recursive part bunnyEars(bunnies-1); should have 1 left in the bracket after subtraction and thus 2+(1); should be equal to 3 and not 4.
It seems you're misreading the expression. The line of code in question says
return 2+bunnyEars(bunnies-1);
Now you call bunnyEars(2), so bunnies == 2; and then you reach this line of code.
return 2+bunnyEars(bunnies-1);
resolves to
return 2+bunnyEars(2-1);
or
return 2+bunnyEars(1);
So a second instance of the bunnyEars() function starts running, with bunnies == 1. It reaches that same line of code, and this time
return 2+bunnyEars(bunnies-1);
is
return 2+bunnyEars(1-1);
or
return 2+bunnyEars(0);
So a third instance of bunnyEars() gets running, with bunnies == 0; but this matches your base case, so you just return 0 ; this time we don't recurse. So back up a level we find that
return 2+bunnyEars(0);
is
return 2+0; // because bunnyEars(0) returned 0
so that instance returns 2. And that means
return 2+bunnyEars(1);
becomes
return 2+2; // because bunnyEars(1) returned 2
And of course 2+2 is 4, the correct answer.
It seems as though you applied the -1 to the return value of the recursive bunnyEars() call, but the code says to apply it to the parameter you're sending in, not to the return value.

Reversing recursive java methods

I am reading a book called "Think Java: How to think like a Computer Scientist", and I recently covered recursive methods.
public static void countdown(int n)
{
if (n == 0) {
System.out.println("Blastoff!");
} else {
System.out.println(n);
countdown(n - 1);
}
}
This would be a normal recursive method used to count down to 0 and I understand what is happening, but if you make the recursive call before the System.out.println like this
public static void countdown(int n)
{
if (n == 0) {
System.out.println("Blastoff!");
} else {
countdown(n - 1);
System.out.println(n);
}
}
it counts the opposite way, so If I gave the argument 3 for both of these conditional statements the 1st one goes "3, 2, 1, Blastoff!" but the 2nd 1 goes "Blastoff, 1 ,2 ,3".... I don't understand how this works, can someone try to explain what is happening in this code that makes it count in the opposite way?
I'll try to visualize it for you.
First method
countdown(3) (first call)
"3" (sysout)
countdown(3-1) (second call)
"2" (sysout)
countdown(2-1) (third call)
"1" (sysout)
countdown(1-1) (fourth call)
"Blastoff!" (n == 0)
Second method
countdown(3) (first call)
countdown(3-1) (second call)
countdown(2-1) (third call)
countdown(1-1) (fourth call)
"Blastoff!" (n == 0. going back up call stack)
"1" (sysout)
"2" (sysout)
"3" (sysout)
Think of it this way... In the first case you will always print before going down the next function, so...
countdown(3)
System.out.println(3)
countdown(2)
System.out.println(2)
countdown(1)
System.out.println(1)
countdown(0)
System.out.println("Blastoff")
Result: 3 2 1 Blastoff
In the second case, because you print it first, your run will go all the way down the recursion until the base case to start printing...
countdown(3)
countdown(2)
countdown(1)
countdown(0)
System.out.println("Blastoff")
System.out.println(1)
System.out.println(2)
System.out.println(1)
Result: 1 2 3 Blastoff
Recursion is tough! I hope I helped :)
It doesn't count "the opposite way", it's just that it "unravels" in an order you are perhaps not expecting. Try writing out what you expect to happen and I'll be happy to help resolve the misconception.
The issue is that the print line is going to wait until your function call(s) have finished. Therefore it will call the function 3 times in a row before it gets to the first print line
The whole point of recursion is that every step gets its own "stack frame" with its own local variables, that it remembers.
So even if you change n inside of one iteration, the function that called this iteration will still retain its own value of n. When the time comes to print this n it will still be the original value (one bigger than the one in the following iteration).

What happens when recursion is called twice in a method?

I'm pretty new to programming and I have now come to the concept of recursion. I have solved a few basic assignments but when I come to multible recursion I get terribly lost. I have tried to solve the following recursion several times but just cant get it right.
A recursive method is called with the arguments "ABCD" and 2, i.e. recMethod("ABCD", 2);.
public void recMethod( String str, int n ) {
if( n >= 0 ) {
recMethod(str, n – 1);
System.out.print(str.charAt(n));
recMethod(str, n – 1);
}
}
Is there somebody out there who can explain what is going on? The first recursive call really confuses me.
The best way to understand recursion as for me is to write it on the paper line by line. What I did for your case now.
Please try to do the same, and don't hesitate to ask more question, I hope it helps!
The most important thing to know about recursion is that it's nothing special. As with everything in a method it needs to finish a statement before the next statement can be executed:
public void someMethod() {
someOtherMethod();
someLastMethod();
}
Looking at my example it's obvious that someLastMethod will be called after someOtherMethod has finished. It really doesn't matter if you replace someOtherMethod with something recursive. It needs to finish before someLastMethod can be called. When looking at your recursive method again:
public void recMethod( String str, int n ) {
if( n >= 0 ) {
recMethod( str, n – 1 );
System.out.print( str.charAt( n ) );
recMethod( str, n – 1 );
} else { // base case added for clarity
return;
}
}
For each call where n >= 0, before the System.out.print method is called the call to recMethod has to be called. Every call to recMethod has it's own n and str so they can be considered different methods entirely except their code is 'very similar'.
Every call will either match base case or need the result of the same method with n decremented so I like to start from the base case and work myself backwards, which is when n is -1. Imagine you call recMethod("ABCD",-1) what would happen? Well it prints nothing or "".
I then look at recMethod("ABCD",0) and it calls the base case, which we know does nothing, then prints "A" and then it calls the same as the first statement which again does nothing. Thus it prints "A"
If we look at recMethod("ABCD",1). We know it calls recMethod("ABCD",0) which prints "A", then it prints "B", then call recMethod("ABCD",0) which prints "A". Thus it prints "ABA"
If we look at recMethod("ABCD",2). We know it calls recMethod("ABCD",1) which prints "ABA", then it prints "C", then call recMethod("ABCD",1) which prints "ABA". Thus it prints "ABACABA"
If we look at recMethod("ABCD",3). We know it calls recMethod("ABCD",2) which prints "ABACABA", then it prints "D", then call recMethod("ABCD",2) which prints "ABACABA". Thus it prints "ABACABADABACABA"
Since "abcd".charAt(4) won't work it doesn't make sense to go on. Perhaps the code should have a test for this or perhaps it should be private and have a public one without n that guarantees n never goes beyond str bounds?
If you were to make a method that works recursively you do the same.
What should happen for the base case. (How should it stop)
What should happen if it's not the base case expressed as if the method works as intended. The catch here is that you need to make sure that each call to the same method here is a slightly simpler problem which the recursion is bound to hit a base case or else you get infinite recursion!
Thats it! It will work.

prefix and postfix increments while comparing variables

could someone explain why this code output is
not equals
not equals 2
in the first if statement it seems that a = 0 b/c is a postfix increment; therefore a will not increase untile next line; however, the two a's are not equal why? and in the second if when I run the debugger the value of a is 2, but the test is false, why?
public static void main (String[] args)
{
int a = 0;
if (a++ == a++) {
System.out.println("equals");
} else {
System.out.println("not equals");
}
if (++a == 2) {
System.out.println("equals 2");
} else {
System.out.println("not equals 2");
}
}
it's not that it waits until the next line. The == is a 'logical' operator so the expression on each side is evaluated first, each of which has the side-effect of incrementing the 'a' value. The result of the 1st increment is used on LHS, result of 2nd on RHS.
In these cases it matters not whether the operator is 'prefix' or 'postfix'
a++(post increment) would increment a first and then assign it to the variable. in your first case
(a++==a++) in the first post increment a value would be incremented by 1 first but not assigned yet, but when it reaches the second a++, now the a value is assigned and you are incrementing it again.
for example
if say a=0;
(a++==a++) would be (0==1)
so now the a value would be 2 after evaluating the if.
for your second case
(++a==2) here a would be incremented to 3 , (3==2) which is false thus the else if executed
EDIT: just realized you asked also for first not equals, this just answers the second one yet.
Because
a is already 2 (already incremented twice)
++a is 3 so
3 == 2 is false since prefix is applied before evaluation.

Categories

Resources