Do IF statements conflict each other if they cover the same thing? - java

If you have two if statements for:
int n = -1;
if (n < 0)
return null;
if (n <= 1)
return "yay";
Will it return null or yay? Will it run through the code top to bottom and stop at the first if statement, or will the last one be used?

The first if statement will be evaluated first, of course. n which is -1 is in fact < 0, so the body of code associated with that if statement will be executed. null will be returned.
What might be confusing you is that, though the second if statement would evaluate true, it will never be evaluated. This is because a return statement, when executed, leaves the function/method it is inside of.
If you wrote:
int x = 0;
return x;
x = 5;
x would be set to 0. x would be returned. Any lines of code after the return would never execute.
Here's another example, to clarify:
int x = 10;
if(x < 0)
return;
x = 0;
x would be set to 10. x which is 10 is in fact not < 0, so the if statement's body will be skipped. x would be set to 0.

it will return null, only because returning (in the first test) means the 2nd test will not be executed.

it will return null, as it's the first condition that matches. After the return the rest of the function isn't executed, and a function is executed sequentially, so they will never conflict.
Another sample of 'conflicting if statements' is when you create code that cannot be reached, for example:
if (n < 0)
return "a";
if (n == -1)
return "b";
This code will never return "b", and the compiler will probably error or warn about it. The reason is that when n = -1, the first statement is always hit, so the second statement is never reached.

It returns null, because it is the first return it encounters. It doesn't even check the second exception.
When the code is run, JVM checks condition in the first if and, when condition is met, it executes what's inside this if. If there is return null then it returns null. After return no code is executed in this method. The only exception is when you have return in try block and finally block after this try.

This is just a small re-format of your code with some explicit comments. I find that the explicit braces help some people see what is going on. Just follow the program flow. If the function is returned from, then no subsequent statements in the function are ever executed. (This is a white lie, see 'finally' Exception handling, but barring that...) -- it's a very procedural (step-by-step) process.
int n = -1;
if (n < 0) {
return null; // no other statement in this function will be executed
// if this line is reached
}
if (n <= 1) {
return "yay"; // no other statement in this function will be executed
// if this line is reached
}

It'll return null.
btw in Java "If" is invalid, you have to use "if" and round brackets for ifs

Will it run through the code top to bottom and stop at the first IF statement
Yes, it will. If it does turn out that n < 0, then it will immediately return null. (I don't know why you tagged this question as Java though, the code you posted is not Java code.)

Will return null. Once you hit the return statement control passes back to the calling function setting the return value of the function to what you specify after the return keyword.

It will return null. The only value for the code you posted that would ever result in 'Yay' being returned would be 0.

Related

recursive function called with different values

I have a recursive function like this:
public static int h(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
} else {
//variable value is a fixed one.
i = value % 2;
return h(n - h(i) - 1) + h(n - 2);
}
}
Suppose the value of variable value is even at this time.Then if I call the function with h(12) I want to know how the function works?
In this case what I want to happen is evaluate
h(12)=h[12-h(0)-1]+h(10)
=h(11)+h(10)
={h(11-h(0)-1)+h(9)}+{h(10-h(0)-1)+h(8)}
={h(10)+h(9)}+{h(9)+h(8)}
Here when evaluating h(11)+h(10) does the function first finish h(11) and get a value for that before starting with h(n-2) which is this case h(10).
If it first finish h(11) then finally it has to reach n==0 or n==1 case.Then by the time it reaches wouldn't h(n-2) be h(-2) or h(-1).
How can I store the initial function call value of 12 and when it reaches h(n-2) to call as h(10) and then make that part to evaluate as h(8),h(6)..
Each function call stores its own copy of arguments. So, call to h(11) won't change n in the first call (h(12)).
Expressions in Java are evaluated from left to right. This means that the call h(11) would finish before h(10) is called from h(12). However, in this case this is not important, since the result would be the same either way.

i do not understand the comparison

Im currently going over MIT courseware for java and am unsure why there is a piece of code involved. I tried removing the code to determine if it is necessary and it kept the program from running.
I have two arrays, one is names of runners, the other is their times. the goal is to find the index of the lowest (fastest) time and then also give the person with the second fastest time. i.e the command prompt will output john is the fastest and kate is the second fastest
the part i am confused about is "secondIndex == -1 ||" --- why is this here? if i remove it i get the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
public static int getSecondIndex(int[] values) {
int minIndex = getMinIndex(values);
int secondIndex = -1;
for(int i = 0; i < values.length; i++) {
if(i == minIndex){
continue;
}
if(secondIndex == -1 ||
values[i] < values[secondIndex]) {
secondIndex = i;
}
}
return secondIndex;
}
It will then evaluate values[secondIndex] which does not have an entry at index -1. The || short circuits from left to right so in the case of secondIndex = -1, values[secondIndex] will never be evaluated.
It's because the loop checks if the current runner's time is less than any time found so far, but when it checks the first runner there is no "fastest runner so far" to compare to. So the check first makes sure that secondIndex has been set at least once before. If it hasn't, the second part of the or statement will never get evaluated (called short-circuit evaluation).
The reason it's there is because of how indexOf works: it can only find things that live on index 0 or higher, so if it cannot find anything, it returns -1.
As such, we compare to -1 to see whether or not something was found at all. If it wasn't, we don't need to waste any more time on it:
if(thing.indexOf(otherthing) == -1) {
// the search failed
}
if it was, we can use the result to immediately look it by using the result of indexOf as an array index.
This condition (secondIndex == -1) is true in the case that secondIndex has not yet been found. Remember that since || is a short circuit operator, if the first condition is true, the second one will not be evaluated. Therefore, if secondIndex is -1, values[secondIndex] will never be evaluated (which is good, because doing so would cause the ArrayIndexOutOfBoundsException).

Understanding basic recursion function in Java to calculate positive integers in array

I am trying to learn recursion in Java and have an array that takes in continuous input until the Scanner reads in a 0.
From there I have a method that (attempts) to calculate the number of positive integers in the array using recursion. This is the first recursive function I have ever written and I keep getting a stackoverflow error.
I have read tutorials and I still can't wrap my head around the basic understanding of recursion.
public class reuncF {
private static int start = 0;
private static int end = 98;
public static void main(String[] args) {
input = input.nextDouble();
list[i] = numInput;
computeSumPositive(numList, count);
}
}
return positives += solve(numbers, count++);
}
}
You forgot to stop your recursion!
There has to be some case where computeSumPositive returns without calling itself again. Otherwise it'll just keep going forever, never getting back to you.
If you did it with a loop, the loop would look like this:
int positives = 0;
for (int i = 0; i < numList.length; ++i) {
if (numList[i] > 0) {
positives++;
}
}
To do that recursively, you just find out what are the variables used in the loop. They are i, numList and positives.
computeSumPositive(int i, double[] numList, int positives)
Then we take a look at what the loop does. First, it checks whether we went too far,
so our recursive function should do that too. It'll have to return instead of just falling through like the loop does. And obviously, it must return the result:
{
if (! (i < numList.length))
return positives;
The loop then does the test and maybe increments positives, so the recursive function should also do that:
if (numList[i] > 0) {
positives++;
}
At the end of the loop, i is updated:
i++;
The loop just starts over, but the recursive function will have to call itself. Of course, we want it to use the new value of i and positives, but fortunately we updated those, so now we can just do:
return computeSumPositives (i, numList, positives);
}
The tricky bit is that the values i, numList, and are local to each call. Each invocation of computeSumPositives can see only the arguments it were given. If it changes them, none of the other invocation can see that change.
EDIT: So if we, for reasons we can only speculate about, wanted desperately for computeSumPositive to take only 2 parameters, we would have to "split up" positives across each invocation. Each invocation knows whether or not its number was positive or not; all we have to do is add them. Then it looks like this:
computeSumPositive(int i, double[] numList)
{
if (! (i < numList.length))
return 0; // I didn't find any at index i
if (numList[i] > 0) {
// Theres one I found + however many my later
// invocations will find.
return 1 + computeSumPositive (i+1, numList);
} else {
// I didn't find any, but my later invocations might.
return computeSumPositive (i+1, numList);
}
}
I find it helpful, when dealing with recursion, to figure out the termination case first.
It looks like you are treating 'count' as an index. So you could check if your at the last index in the array, if so and if the value is positive return a 1, if the value is non-positive return a 0 - dont recurse anymore.
If your not at the last index, and the value is positive return a 1 + the recursive function call, or if the value is non-positive just continue to recurse.
This will still cause a stack overflow for large arrays.
The value of count++ is the same as the value of count; the program uses the value and then increments it. But the result is that computeSumPositive keeps calling itself with the same value of count, which leads to infinite recursion. Note that each time computeSumPositive calls another computeSumPositive, each call has its own copy of the parameters (like count) and the local variables; so incrementing one computeSumPositive's copy of count has no effect on the value of count used by other recursive calls.
Change count++ to count + 1, and also add a way to halt the recursion. (At some point, you will be calling computeSumPositive to look at zero integers, and at that point, it should just return 0 and not call itself. You need to think about: how do you test whether you've reached that point?)

Is this a proper use of recursion?

I made what I think is an example of recursion. Is this acceptable? It's not for a project or anything, my professor is just awful so I try to teach myself.
public void theCat() {
int i;
for (i = 0; i <= 50; i++) {
System.out.println(i);
if (i == 10) {
theCat();
}
}
}
Yes, that is recursion. However, it will be infinite since you never stop it.
What you should do is to have a base case where you check if it is time to stop the recursion. You would also have a reduction step, that will converge the parameter towards the base case, like so:
public int theCat(int i) {
if (i => 50)
return i;
else
return theCat(i + 1);
}
To show the effectiveness of this, have a look at a recursive factorial method:
private long factorial(int n) {
if (n == 1)
return 1;
else
return n * factorial(n-1);
}
Here, the base case checks if we are trying to calculate 1! and in that case returns 1. This is the case where we no longer need to recursively call the method. Instead, we walk backwards along all of the method calls we have made to calculate the final answer:
factorial(5)
factorial(4)
factorial(3)
factorial(2)
factorial(1)
return 1
return 2*1 = 2
return 3*2 = 6
return 4*6 = 24
return 5*24 = 120
This will cause overflow. All recursion should have some kind of base case for exiting so that it does not go infinitely.
Additionally all recursive functions usually receive some kind of an int or some value so that they can use that value in the base case and exit. So for your example I would send int i as an argument into cat and stop when i == 50
Yes and no. Technically this is an example of recursion. But this will never terminate. Normally there is some parameter passed into a recursive method so that it can recognize a "base case" which will not recurse.
Yes, but you must have flag that determine exit from your method, otherwise you catch StackOverFlowError
That will cause a stack overflow as the recursive call is infinite.
We can define recursion in this way:
1. we start with a method that has a specific state
2. inside this method the method itself is called, but the call changes the state of the method
3. the method has a base case (a case where if a method reaches this state it no longer calls itself recursively).

If-else block in nested for loops - Compiler claims I need a return statement

How do I make this work? It says that I need to add a return statement but I have one.
public boolean clockFactCheck(int a, int b){
for (int i = 0; i <= 276; i++){
for (int h = 0; h <= 55; h++){
if (a == i + 186 && b == h + 133){
return true;
} else {
return false;
}
}
}
}
The code provided may not reach one of the returns for any input a,b and that's what the compiler is complaining about.
Actually in your case the if-else will be reached with the very first iteration - unfortunately something which the compiler cannot deduce. Therefore, it goes the save way and issues this error.
Comment: Therefore, in your loop seems not to make much sense since it will not iterate at all but stop within the first iteration i==0 and h==0. Did you meant to code something like that?
You don't have a return statement after the for loop but even then h++ is dead code becaue it will never get past the first iteration.
Place the return statement outside the loop. (declare a boolean in your function, modify it and return it at the end)
My guess is that the compiler is not clever enough to figure out that there is no codepath around the loops.
If this is real code, simplify it to
return (a == 186 && b == 133);
If this is not the real code, there is probably another path that does not return (if you made an error pasting), or there really is a compiler bug or limitation. At one point, the halting problem bites you, and the code is too complex for the compiler to figure out.
In the latter case I would place a
throw new RuntimeException(
String.format("should never get here (a = %d, b = %d) !",a,b));
at the last statement.
That makes both the compiler happy and does not introduce an "undefined" return value for a case that should either never happen, or if it does, has not been thought of.
Oh yeah my bad, I'm sorry this was a stupid question it was 5am when I posted this. I figured out the answer to my problem. If you made the same stupid mistake as me here is the fix
public boolean clockFactCheck(int a, int b){
for (int i = 0; i <= 276; i++){
for (int h = 0; h <= 55; h++){
if (a == i + 186 && b == h + 133){
return true;
}
}
}
return false;
}
Java requires every path return a value. The compiler could not judge if the circulation will return a path. If your code is like this:
public boolean add(){
for(int i=0;i<100;i++)
if(i==5000)
return true;}
the function add will not return a value. Instead, an error will occur.

Categories