I am trying to practice understanding recursion but the following program has me stumped. How is the answer being returned as 14? Can someone show me how this is calculating? I tried to put in afew print statments to help me identify what is going on but I do not see how spot is decremented after it goes up to 4. I have the program and output to console below, please help.
from console:
The spot 1 is 0
The spot 1 is 1
The spot 1 is 2
The spot 1 is 3
The spot 1 is 4
when spot = length. the spot is 4
The value is 4
spot after return 3
the spot 2 is 3
The value is 8
spot after return 2
the spot 2 is 2
The value is 11
spot after return 1
the spot 2 is 1
The value is 13
spot after return 0
the spot 2 is 0
The answer is 14
Code:
public class Recurs1 {
public static void main (String [] arg) {
Recurs1 r = new Recurs1();
r.compute();
}
public void compute() {
int [] stuff = {1, 2, 3, 4};
int answer = go(stuff, 0);
System.out.println("The answer is " + answer);
}
private int go(int[] numbers, int spot) {
System.out.println("The spot 1 is " + spot);
//System.out.println("0 is " + numbers[0] + " 1 is " + numbers[1] + " 2 is " + numbers[2] + " 1 is " + numbers[3]);
if (numbers.length == spot) {
System.out.println("when spot = length. the spot is " + spot); return spot;
}
int value = go(numbers, spot + 1 );
System.out.println(" The value is " + value);
System.out.println("spot after return " + spot);
System.out.println(" the spot 2 is " + spot);
return value + numbers[spot];
}
}
Try returning 0 instead of spot when you've reached the end. You're tacking 4 (the current value of spot) onto the end.
If your goal is to write a method which is summing the array, then the problem is that on the line of go() where you have if(numbers.length == spot) you are returning spot, which is 4, and it is adding that to the total value (because the method that called go(numbers, 4) is setting value to that and adding it.) Instead, you should be returning 0 to stop recursion (because the result will be 1+2+3+4+0)
Try this on for size:
private int go(int[] numbers, int spot){
if(numbers.length == spot) return 0;
return go(numbers, spot+1) + numbers[spot];
}
Maybe I can help walk you through it. Your program works it's way up until it calls go(numbers, 3+1), which returns 4, because numbers has 4 elements and spot is of value 4 (3+1).
At this point you are looking at a call stack of something like this:
answer = go(stuff, 0);
value = go(numbers, 0 + 1);
value = go(numbers, 1 + 1);
value = go(numbers, 2 + 1);
value = go(numbers, 3 + 1) = 4
Now it will work it's way back up the stack.
go(numbers, 2 + 1 );
Calling this will give you value+numbers[3], which is 4 + 4, with value coming from go(numbers, 3 + 1).
Next we have
go(numbers, 1 + 1 );
This will return go(numbers, 2 + 1 ) + numbers[2], which is 8 + 3 (or 11).
And then go(numbers, 0 + 1 ) is called, which returns go(numbers, 1 + 1 ) + numbers[1], which is 11 + 2 or 13.
Lastly, go(stuff, 0) can be calculated. This returns go(numbers, 0 + 1 ) + numbers[0], which is 13+1, or 14 - the answer you are currently getting.
I'm not sure if I actually explained much, but hopefully walking through it can show where your confusion is.
Another way of visualizing it would be something like this:
answer = go(stuff, 0);
go(stuff, 0) = go(numbers, 0 + 1) + 1;
go(numbers, 0 + 1) = go(numbers, 1 + 1) + 2;
go(numbers, 1 + 1) = go(numbers, 2 + 1) + 3;
go(numbers, 2 + 1) = go(numbers, 3 + 1) + 4;
go(numbers, 3 + 1) = 4;
Related
I need to write a function (in Java) which has the following input:
int amountFieldElements
int summandOne
int summandTwo
amountFieldElement describes the amount of int numbers in a range starting from 1 (e.g. 1, 2, 3, 4 or just 1). summandOne is a int from this range, summandTwo can be any non-negative int.
The function has to add summandTwo to summandOne. If the result is bigger then amountFieldElement, it has to start over from 1.
I tried to simply use modulo: (summandOne + summandTwo) % amountFieldElements
But this is often wrong, e.g. (3 + 1) % 4 = 0 but I'd need it to be 4.
Example: If amountFieldElements = 4:
2 + 2 = 4 would stay as 4
3 + 2 = 5 would become 1
4 + 2 = 6 would become 2 etc
or for amountFieldElements = 1
1 + 0 = 1 would stay as 1
1 + 1 = 2 would also be 1
-> any result would be 1 here
something like this will work:
int result = (summandOne + summandTwo) % amountFieldElements;
if (result == 0) result = amountFieldElements;
another method, shorter but harder to understand is:
int result = (summandOne + summandTwo - 1) % amountFieldElements + 1;
I am having some problems with Recursion in Java.
Here is my code
public class recursionTrial {
public static void main(String[] args)
{
System.out.println(doSomething(6));
}
public static int doSomething(int n)
{
if (n==0 || n==1)
return 0;
else
return n + doSomething(n-1) + doSomething(n-2);
}
}
Which gives me an output of 38. However I am unable to trace the recursive function in my head or on paper. How will the working out look? 6+5.... and so on.
I get if it were just
return n + doSomething(n-1)
then it would be 6+5+4+3+2 = 20 ; it is the second part of the code that is confusing me. If someone could explain to me how to trace the recursive function properly and write the working out I would appreciate it! Also is there a way to write a piece of code that prints the value of n before it changes each time?
In the absence of side effects one can think of this recursive function as of a regular function. You can draw a small table showing the results of invocation of your function, starting with zero:
n res computation
- --- -----------
0 0 0
1 0 0
2 2 2+0+0
3 5 3+2+0
4 11 4+5+2
5 21 5+11+5
6 38 6+21+11
No special mental treatment is required for the second recursive invocation: it is the same as the first one.
Note: your function will be taking progressively longer time as the value of n goes up, because it would be re-doing a lot of computations it has already done. Fortunately, this can be addressed with a simple and very common trick, called memoization.
Your recursive function is
f(n) = n + f(n-2) + f(n-1)
The execution flow is as follows.
f(n-2) is evaluated first... To compute f(n-2) the program again makes a recursive call to f(n-4) and f(n-3) and so on...
Next, f(n-1) is evaluated... this again depends on computed values of f(n-3) and f(n-2) and so on...
These two values are added with n to get the final result...
For example, the recursion tree for n=4 is as follows (I'm not showing the addition with n for simplicity):
f(4) {
f(2) {
f(0) {0}
f(1) {0}
}
f(3) {
f(1) {0}
f(2) {
f(0) {0}
f(1) {0}
}
}
}
doSomething(1)= return 0,
doSomething(2)== 2+dosomething(1)= 2+0=2,
doSomething(3)=3+doSomething(2)=3+2=5,
doSomething(4)=4+doSomething(3)+doSomething(2)=4+5+2=11
doSomething(5)=5+doSomething(4)+doSomething(3)=5+11+5=21,
doSomething(6)=6+doSomething(5)+doSomething(4)=6+21+11=38
Start at doSomething(6), it calls: doSomething(5) go to that line, to figure out doSomething(5) we need to know doSomething(4) and doSomething(3).... and work your way up the tree, till you get to an actual "Return value" which in this case would be when we reach doSomething(1), then put those values in as you back down the tree.
public static int doSomething(int n) {
if (n==0 || n==1)
return 0;
else
return n + doSomething(n-1) + doSomething(n-2);
}
You could try to expand recursively, this is conceptually what the program does.
doSomething(6) expands to 6 + doSomething(5) + doSomething(4)
doSomething(5) expands to 5 + doSomething(4) + doSomething(3)
doSomething(4) expands to 4 + doSomething(3) + doSomething(2)
...
Simply go down the recursion. For example (I use dS for doSomething):
dS(6) = 6 + dS(5) + dS(4) =
6 + 5 + dS(4) + dS(3) + 4 + dS(3) + dS(2) =
6 + 5 + 4 + dS(3) + dS(2) + 3 + dS(2) + dS(1) + 4 + 3 + dS(2) + dS(1) + 2 + dS(1) + dS(0) =
6 + 5 + 4 + 3 + dS(2) + dS(1) + 2 + dS(1) + dS(0) + 3 + 2 + dS(1) + dS(0) + 0 + 4 + 3 + 2 + dS(1) + dS(0) + 0 + 2 + 0 + 0 =
6 + 5 + 4 + 3 + 2 + dS(1) + dS(0) + 0 + 2 + 0 + 0 + 3 + 2 + dS(1) + 0 + 0 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 =
6 + 5 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 + 3 + 2 + 0 + 0 + 0 + 4 + 3 + 2 + 0 + 0 + 0 + 2 + 0 + 0 =
38 <-- Final result
Beware that this has exponential complexity.
doSomething(6) calls doSomething(5) and doSomething(4)
doSomething(5) calls doSomething(4) and doSomething(3)
doSomething(4) calls doSomething(3) and doSomething(2)
doSomething(3) calls doSomething(2) and doSomething(1)
doSomething(2) calls doSomething(1) and doSomething(0)
doSomething(1) is 0
doSomething(0) is 0
This illustrates callings of doSomething(), they are not results, since you are adding n for each call.
6
_______|_______
/ \
5 4
____|____ _|_
/ \ / \
4 3 3 2
_|_ | | |
/ \ / \ / \ / \
3 2 2 1 2 1 1 0
/ \ / \ / \ / \
2 1 1 0 1 0 1 0
/ \
1 0
I saw this code online but what I am asking is how did the program come up with an answer of 12 ?
I did a tracing of the program, and I only come up with an answer of 6 .
Why is the answer 12 ?
The inputs are a=6 and b=6.
This is the code:
public static int addxy(int a, int b)
{
if (a==0)
return b;
else if (b==0)
return a;
else
return 1 + addxy(a, b-1);
}
addxy(6,6)
1+addxy(6,5)
1+1+addxy(6,4)
1+1+1+addxy(6,3)
1+1+1+1addxy(6,2)
1+1+1+1+1+addxy(6,1)
1+1+1+1+1+1+addxy(6,0) = 12
Try walking over it step by step:
addxy(6, 6) returns 1 + addxy(6, 5)
addxy(6, 5) returns 1 + addxy(6, 4)
addxy(6, 4) returns 1 + addxy(6, 3)
addxy(6, 3) returns 1 + addxy(6, 2)
addxy(6, 2) returns 1 + addxy(6, 1)
addxy(6, 1) returns 1 + addxy(6, 0)
addxy(6, 0) returns 6
So, addxy(6, 1) returns 1 + 6 = 7
So, addxy(6, 2) returns 1 + 7 = 8
So, addxy(6, 3) returns 1 + 8 = 9
So, addxy(6, 4) returns 1 + 9 = 10
So, addxy(6, 5) returns 1 + 10 = 11
So, addxy(6, 6) returns 1 + 11 = 12
This
return 1 + addxy(a, b-1);
returns 1 plus the result of calling the method recursively while removing 1 from b. This basically means that it adds b.
When b is 0, you return a.
else if (b==0)
return a;
(You also return b, when a is 0.
Without even tracing anything, you can tell that (with non-negative values for a and b) the method simply adds a and b and returns the result.
Look at the return statement
return 1 + addxy(a, b-1);
You have a function call in the return statement to the same function. This is called a recursive function. So as long as b is not 0, it keeps on calling it again n again but by adding 1 and subtracting b by 1. This goes on till b becomes 0. Which is 6 times. And thats why you get 1*6 + a = 6
Equivalent execution would be
return 1 + addxy(6, 5);
return 1 + 1 + addxy(6, 4);
return 1 + 1 + 1 + addxy(6, 3);
return 1 + 1 + 1 + 1 + addxy(6, 2);
return 1 + 1 + 1 + 1 + 1 + addxy(6, 1);
return 1 + 1 + 1 + 1 + 1 + 1 + addxy(6, 0);
return 1 + 1 + 1 + 1 + 1 + 1 + 6; // Value of a = 6
return 12;
As #Mureinik answer is perfect but you didn't understand it ,
So Lets start with a very basic example of Calculating Factorial via Recursion:
public int factorial(int num){
if(num==0) //break condition of Recursion Since 0! is always 1
return 1;
return num*fact(num-1);
}
So here is the Tracing
factorial(4) return 4*factorial(3);
factorial(3) return 3*factorial(2);
factorial(2) return 2*factorial(1);
factorial(1) return 1*factorial(0);
factorial(0) returns 1;
, Now backtrace this answers and this below image is formed
May Be now you are able to understand it
public static boolean binarySearch(int[] data, int value){
int start = 0;
int end = data.length-1;
int middle = (start + end) / 2;
while(end >= start){
if(data[middle] == value){
System.out.println("binarySearch found value " + value + " at position " + data[middle]);
return true;
}
if(data[middle] < value){
start = middle + 1;
}
if(data[middle] > value){
end = middle + 1;
}
}
return false;
}
I have this code for binary search, and to me it looks like everything is in check. But when i pass an array and a variable I'm looking for through it it doesn't give me anything in return and I just have to terminate it. Any thoughts?
if(data[middle] == value)
this part checks if the middle of the array equals to data all the time. If you don't modify the variable middle, no matter what you do, it will always check if the middle value is equal to data.
Since you don't modify start and end as well,
while(end >= start)
this part also prevents you to finish the loop.
This is what I tried:
int data[] = {1, 3, 4, 5, 7, 8, 12};
int value = 7;
binarySearch(data, value);
And this is the output I get when I add
System.out.println("Start: " + start +
" Middle: " + middle + " End: " + end);
at the beginning of while loop:
Start: 4 Middle: 3 End: 6
Start: 4 Middle: 3 End: 6
Start: 4 Middle: 3 End: 6
Start: 4 Middle: 3 End: 6
Start: 4 Middle: 3 End: 6
Start: 4 Middle: 3 End: 6
Start: 4 Middle: 3 End: 6
...
to infinity.
in this code im confused as to why it prints out "0 1 2 3" instead of "3 2 1 0"
int y = 3;
String s = " ";
while (y>-1)
{
s = y + " " + s;
y--;
}
System.out.print(s);
Thanks.
s = y + " " + s;
adds y at the front of the string so:
s = 3
s = 2 3
s = 1 2 3
s = 0 1 2 3
step 1:
s = 3
step 2:
s = 2 3;
step 3:
s = 1 2 3
like wise in every loop y's value is added to the starting point of the string s
This is because you prepend the newest value to the string. If you want the output to be "3 2 1 0" you should change your line from
s = y + " " + s;
to
s = s + " " + y;