I\'m new to programming so I have been working through the exercises at CodingBat.com. In the Recursion-2 section, there is a problem I wasn\'t able to solve (recursively) so I
This statement returns true if either of the terms is true.
Returns a boolean...
> public boolean split53(int[] nums) {
true || false
is true
, false || false
is false
, etc.
return helper(start + 1, nums, sum1 + nums[start], sum2)
|| helper(start + 1, nums, sum1, sum2 + nums[start]);
returns true
if either call to helper()
returns true. Here is the same code written a different but functionally equivalent way:
boolean helperResponse1 = helper(start + 1, nums, sum1 + nums[start], sum2);
if (helperResponse1 == true)
return true;
else {
boolean helperResponse2 = helper(start + 1, nums, sum1, sum2 + nums[start]);
if (helperResponse2 == true)
return true;
else
return false;
}
I put in a lot of unnecessary stuff for the sake of clarity.
return a || b;
does not mean:
return a || return b;
It actually means:
return (a || b);
It will evaluate a || b
, and then return the result of that:
So if a
or b
is true
(either one, or both, are true
), it will return true
. It will only be false
if a
and b
are both false.
The point is: it evaluates the boolean expression first, then returns the value.
Edit: You can look at this test code for examples on how it works.
First we have bitwise operations |
(or) and &
(and) and they will evaluate both sides to get the answer. However if you were to do a recursive function with that it would do both sides unconditionally. If you are unfamiliar with or and and here are the truth tables:
+-------+-------+-------+
| B | A | A|B |
+-------+-------+-------+
| false | false | false |
| false | true | true |
| true | false | true |
| true | true | true |
+-------+-------+-------+
+-------+-------+-------+
| B | A | A&B |
+-------+-------+-------+
| false | false | false |
| false | true | false |
| true | false | false |
| true | true | true |
+-------+-------+-------+
While or is slightly different than what one would expect and is spot on. The fact is for these true | whatever
is true
whatever the right side is and false & whatever
is false
whatever the rightside is. We don't actually need to know the right hand side in those cases or we don't even need to do the calculation that generates that value either. ||
and &&
is the same as |
and &
except it won't evaluate more than it needs. Below is a small test you can run:
class Test
{
public static boolean getTrue()
{
System.out.println("returning true");
return true;
}
public static boolean getFalse()
{
System.out.println("returning false");
return false;
}
public static void main(String[]args)
{
System.out.println( "Doing bitwise or");
System.out.println( getFalse() | getFalse() );
System.out.println( getFalse() | getTrue() );
System.out.println( getTrue() | getFalse() );
System.out.println( getTrue() | getTrue() );
System.out.println( "Doing conditional (short-circuiting) or");
System.out.println( getFalse() || getFalse() );
System.out.println( getFalse() || getTrue() );
System.out.println( getTrue() || getFalse() ); // won't evaluate right side
System.out.println( getTrue() || getTrue() ); // won't evaluate right side
System.out.println( "Doing bitwise and");
System.out.println( getFalse() & getFalse() );
System.out.println( getFalse() & getTrue() );
System.out.println( getTrue() & getFalse() );
System.out.println( getTrue() & getTrue() );
System.out.println( "Doing conditional (short-circuiting) and");
System.out.println( getFalse() && getFalse() ); // won't evaluate right side
System.out.println( getFalse() && getTrue() ); // won't evaluate right side
System.out.println( getTrue() && getFalse() );
System.out.println( getTrue() && getTrue() );
}
}
So in your code example what does it mean? Well since it's ||
, which is or, if the first helper
call returns true that would end the method and it will become the result. However if it's false
it's the result of the other call that becomes the result of the method.
It could have been written like this instead without changing the result:
boolean tmp = helper(start + 1, nums, sum1 + nums[start], sum2);
if( tmp )
return tmp;
return helper(start + 1, nums, sum1, sum2 + nums[start]);
However the ||
makes it a lot easier to read than this.
Every recursive function needs an ending point. Yours is:
if (start >= nums.length) return sum1 == sum2;
It will return true or false, depending on (sum1 == sum2).
Refering to the statement:
else {return (A || B); }
It will get into the first clause, until its return TRUE or FALSE. If it returns TRUE, it is the end of the line. Else, it will evaluate the second clause and return the match (A || B).
(TRUE || TRUE) -> TRUE
(TRUE || FALSE) -> TRUE
(FALSE || TRUE) -> TRUE
(FALSE || FALSE) -> FALSE