2 recursive calls in function in Java - java

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

Related

Explain the Step by step execution of the recursion code to convert Decimal to Binary in Java

So, this is the code to convert a Decimal number to Binary number using recursion in Java, the code works without any error. But I am confused how does the compiler execute this code, like I was solving it using paper, but I am not able to understand how the compiler takes it and generates the output.
When I was solving it on paper the solution did not make any sense to me. If anybody can tell me how it works, please. Have been sitting on the problem for more than 1 hour now.
I would be happy if somebody describes me the step by step execution of the code and arriving at the same output as the code.
Have used recursion like shown below.
public class RecursionPractice {
public static void main(String[] args) {
System.out.println("The converted number is " + dectoBin(7));
}
private static int dectoBin(int n){
if(n == 0 )
return 0;
else
return n % 2 + 10 * dectoBin(n/2);
}
}
The output is as expected
The converted number is 111
Process finished with exit code 0
Step By Step Execution as follows. Hopefully you'll understand now .
1st call: dectoBin(7) => return 7 % 2 + 10 * dectoBin(7/2); => 1 + 10 * dectoBin(3);
2nd call: dectoBin(3) => return 3 % 2 + 10 * dectoBin(3/2); => 1 + 10 * dectoBin(1);
3rd call: dectoBin(1) => return 1 % 2 + 10 * dectoBin(1/2); => 1 + 10 * dectoBin(0);
4th call: dectoBin(0) => return 0; // base case
Evaluate all of these
dectoBin(7);
7 % 2 + 10 * dectoBin(3);
7 % 2 + 10 * ( 3 % 2 + 10 * dectoBin(1) );
7 % 2 + 10 * ( 3 % 2 + 10 * ( 1 % 2 + 10 * dectoBin(0) ) );
dectoBin(0) returns 0 So,
7 % 2 + 10 * ( 3 % 2 + 10 * ( 1 % 2 + 10 * 0 ) );
7 % 2 + 10 * ( 3 % 2 + 10 * ( 1 ) );
7 % 2 + 10 * ( 11 );
7 % 2 + 110;
1 + 110;
111;
1st Iteration:
7 % 2 + 10 * __
2nd Iteration
3 % 2 + 10 * __
3rd Iteration
1 % 2 + 10 * __
4th Iteration
return 0
3rd Iteration
1 % 2 + 10 * 0 = 1
2nd Iteration
3 % 2 + 10 * 1 = 1 + 10 = 11
1st Iteration:
7 % 2 + 10 * 11 = 1 + 110 = 111
Recursion is a type of loop, if you have a problem to solve in your code (maybe converting a list to string in a special formatting) but that that problem has more instances of the same problem within it (That list has more lists inside of it that needed to be formatted in the same way).
In your example the loop will stop when the decToBin() method is given 0 as an argument. The loop basically goes on and keeps dividing the number by 2 until it gets to 0 or less and then it stops.
Pass 7 to the method:
7%2 + 10 * dectoBin(7/2)= 1 + 10* dectoBin(3). Now n is 3.
(dectoBin(3)): 3%2 + 10* dectoBin(3/2) = 1 + 10 * dectoBin(1). Now n is 1
(dectoBin(1)): 1%2 + 10* dectoBin(1/2) = 1+ 10 * dectoBin(0). Now n is 0
(dectoBin(0)): return 0;
Going backwards: 1 + 10* (1 +10 *(1+10*0))=1+ 10*(1 + 10)= 1 +110 =111

java get all possible variants (positive and negative)

Lets say I got a row of number "1 2 3 4"
I need to get all possible values
1+2+3+4
1+2+3-4
1+2-3+4
1+2-3-4
...
-1-2-3-4
tried to write a recursion
but it kinda works with "1 2" and "1 2 3"
it should work with 1 2 3 ... n
checkSum(0, list.size(), list);
private void checkSum(int start, int end, List<Long> list) {
for (int i = start; i < end; i++){
list.set(i, list.get(i) * (-1L));
printLine(list);
checkSum(i+2, end, list);
}
}
private void printLine(List<Long> list) {
for (int i = 0; i < list.size(); i++) {
if (i > 0)
if (list.get(i) > 0L)
System.out.print("+");
System.out.print(String.valueOf(list.get(i)));
}
System.out.println();
}
I have an approach that can give you some really cool ideas.
I didn't it with recursion, recursion is good, but you need be careful with memory issues when you use it. If you put a big list you can be faced with Stack Overflow errors.
Ok, my solution takes advantage of the binary system.
so, in binary, counting from 0 to 8
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
Have you got it? you can consider the ones as negative signal. You can apply a mask to get the value.
your mask starts with 1 and goes on like:
0 0 0 1
0 0 1 0
0 1 0 0
1 0 0 0
in this way you can test the values.
So, the code:
public static void listPermutation(List<Long> l) {
for (int i = 0; i <= Math.pow(2,l.size()) - 1; i++) {
List<Long> l2 = new ArrayList<Long>(l);
applyMask(l2, i);
}
}
public static void applyMask(List<Long> l, long counter) {
long mask = 1L;
for (int i = l.size() - 1; counter >= mask; i--) {
if ((mask & counter) > 0) // here testing if the bit is 1 or 0
l.set(i, l.get(i) * -1);
mask <<= 1;
}
printLine(l); // System.out.println(l);
}
Example,
List<Long> l = new ArrayList<Long>();
l.add(1l);
l.add(2l);
l.add(3l);
l.add(4l);
listPermutation(l);
results in,
1+2+3+4
1+2+3-4
1+2-3+4
1+2-3-4
1-2+3+4
1-2+3-4
1-2-3+4
1-2-3-4
-1+2+3+4
-1+2+3-4
-1+2-3+4
-1+2-3-4
-1-2+3+4
-1-2+3-4
-1-2-3+4
-1-2-3-4
At point of speed, it's not bad:
List<Long> l = new ArrayList<Long>();
l.addAll(Arrays.asList(new Long[] { 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L }));
long initTime = System.currentTimeMillis();
listPermutation(l);
long finalTime = System.currentTimeMillis();
System.out.println(finalTime - initTime + " ms");
2833 ms
Maybe (probably) this is not the best way to do that, but I'm sure that will improve your mind :)
One of a billion ways of doing it below...
public class Thingy {
public static void main(String[] args) {
printAll(0, 0, Arrays.asList(1L, 2L, 3L, 4L), "TEST1> ");
printAll(0, 0, Arrays.asList(5L, 6L, 3L, 8L, 9L), "TEST2> ");
}
private static void printAll(int i, long accumulator, List<Long> source, String output) {
if(i >= source.size()) {
System.out.println(output + " = " + accumulator);
} else {
long n = source.get(i);
printAll(i + 1, accumulator + n, source, output + " + " + n);
printAll(i + 1, accumulator - n, source, output + " - " + n);
}
}
}
Output...
TEST1> + 1 + 2 + 3 + 4 = 10
TEST1> + 1 + 2 + 3 - 4 = 2
TEST1> + 1 + 2 - 3 + 4 = 4
TEST1> + 1 + 2 - 3 - 4 = -4
TEST1> + 1 - 2 + 3 + 4 = 6
TEST1> + 1 - 2 + 3 - 4 = -2
TEST1> + 1 - 2 - 3 + 4 = 0
TEST1> + 1 - 2 - 3 - 4 = -8
TEST1> - 1 + 2 + 3 + 4 = 8
TEST1> - 1 + 2 + 3 - 4 = 0
TEST1> - 1 + 2 - 3 + 4 = 2
TEST1> - 1 + 2 - 3 - 4 = -6
TEST1> - 1 - 2 + 3 + 4 = 4
TEST1> - 1 - 2 + 3 - 4 = -4
TEST1> - 1 - 2 - 3 + 4 = -2
TEST1> - 1 - 2 - 3 - 4 = -10
TEST2> + 5 + 6 + 3 + 8 + 9 = 31
TEST2> + 5 + 6 + 3 + 8 - 9 = 13
TEST2> + 5 + 6 + 3 - 8 + 9 = 15
TEST2> + 5 + 6 + 3 - 8 - 9 = -3
TEST2> + 5 + 6 - 3 + 8 + 9 = 25
TEST2> + 5 + 6 - 3 + 8 - 9 = 7
TEST2> + 5 + 6 - 3 - 8 + 9 = 9
TEST2> + 5 + 6 - 3 - 8 - 9 = -9
TEST2> + 5 - 6 + 3 + 8 + 9 = 19
TEST2> + 5 - 6 + 3 + 8 - 9 = 1
TEST2> + 5 - 6 + 3 - 8 + 9 = 3
TEST2> + 5 - 6 + 3 - 8 - 9 = -15
TEST2> + 5 - 6 - 3 + 8 + 9 = 13
TEST2> + 5 - 6 - 3 + 8 - 9 = -5
TEST2> + 5 - 6 - 3 - 8 + 9 = -3
TEST2> + 5 - 6 - 3 - 8 - 9 = -21
TEST2> - 5 + 6 + 3 + 8 + 9 = 21
TEST2> - 5 + 6 + 3 + 8 - 9 = 3
TEST2> - 5 + 6 + 3 - 8 + 9 = 5
TEST2> - 5 + 6 + 3 - 8 - 9 = -13
TEST2> - 5 + 6 - 3 + 8 + 9 = 15
TEST2> - 5 + 6 - 3 + 8 - 9 = -3
TEST2> - 5 + 6 - 3 - 8 + 9 = -1
TEST2> - 5 + 6 - 3 - 8 - 9 = -19
TEST2> - 5 - 6 + 3 + 8 + 9 = 9
TEST2> - 5 - 6 + 3 + 8 - 9 = -9
TEST2> - 5 - 6 + 3 - 8 + 9 = -7
TEST2> - 5 - 6 + 3 - 8 - 9 = -25
TEST2> - 5 - 6 - 3 + 8 + 9 = 3
TEST2> - 5 - 6 - 3 + 8 - 9 = -15
TEST2> - 5 - 6 - 3 - 8 + 9 = -13
TEST2> - 5 - 6 - 3 - 8 - 9 = -31
For your interest, a solution using Java 8 streams and no recursion:
public class ComboCollector {
private List<String> list = Collections.singletonList("");
private ComboCollector accept(String n) {
list = Stream.concat(
list.stream().map(v -> v + "+" + n), list.stream().map(v -> v + "-" + n))
.collect(Collectors.toList());
return this;
}
private ComboCollector combine(ComboCollector other) {
other.list.stream().forEach(this::accept);
return this;
}
public Stream<String> getResult() {
return list.stream();
}
}
public static void main(String[] args) {
IntStream.range(1, 10).mapToObj(Integer::toString)
.collect(ComboCollector::new, ComboCollector::accept, ComboCollector::combine)
.getResult().forEach(System.out::println);
}
I'm not necessarily recommending this approach but just wanted to demonstrate a different mechanism than traditional recursion.

Generate all combinations of mathematical expressions that add to target (Java homework/interview)

I've tried to solve the problem below for a coding challenge but could not finish it in 1 hour. I have an idea on how the algorithm works but I'm not quite sure how to best implement it. I have my code and problem below.
The first 12 digits of pi are 314159265358.
We can make these digits into an expression evaluating to 27182 (first 5 digits of e)
as follows:
3141 * 5 / 9 * 26 / 5 * 3 - 5 * 8 = 27182
or
3 + 1 - 415 * 92 + 65358 = 27182
Notice that the order of the input digits is not changed. Operators (+,-,/, or *) are simply inserted to create the expression.
Write a function to take a list of numbers and a target, and return all the ways that those numbers can be formed into expressions evaluating to the target
For example:
f("314159265358", 27182) should print:
3 + 1 - 415 * 92 + 65358 = 27182
3 * 1 + 4 * 159 + 26535 + 8 = 27182
3 / 1 + 4 * 159 + 26535 + 8 = 27182
3 * 14 * 15 + 9 + 26535 + 8 = 27182
3141 * 5 / 9 * 26 / 5 * 3 - 5 * 8 = 27182
This problem is difficult since you can have any combination of numbers and you don't consider one number at a time. I wasn't sure how to do the combinations and recursion for that step. Notice that parentheses are not provided in the solution, however order of operations is preserved.
My goal is to start off with say
{"3"}
then
{"31", "3+1", "3-1", "3*1" "3/1"}
then
{"314", "31+4", "3+1+4", "3-1-4", "31/4", "31*4", "31-4"} etc.
then look at the every value in the list each time and see if it is target value. If it is, add that string to result list.
Here is my code
public static List<String> combinations(String nums, int target)
{
List<String> tempResultList = new ArrayList<String>();
List<String> realResultList = new ArrayList<String>();
String originalNum = Character.toString(nums.charAt(0));
for (int i = 0; i < nums.length(); i++)
{
if (i > 0)
{
originalNum += nums.charAt(i); //start off with a new number to decompose
}
tempResultList.add(originalNum);
char[] originalNumCharArray = originalNum.toCharArray();
for (int j = 0; j < originalNumCharArray.length; j++)
{
//go through every character to find the combinations?
// maybe recursion here instead of iterative would be easier...
}
for (String s : tempResultList)
{
//try to evaluate
int temp = 0;
if (s.contains("*") || s.contains("/") || s.contains("+") || s.contains("-"))
{
//evaluate expression
} else {
//just a number
}
if (temp == target)
{
realResultList.add(s);
}
}
tempResultList.clear();
}
return realResultList;
}
Could someone help with this problem? Looking for an answer with coding in it, since I need help with the generation of possibilities
I don't think it's necessary to build a tree, you should be able to calculate as you go -- you just need to delay additions and subtractions slightly in order to be able take the precedence into account correctly:
static void check(double sum, double previous, String digits, double target, String expr) {
if (digits.length() == 0) {
if (sum + previous == target) {
System.out.println(expr + " = " + target);
}
} else {
for (int i = 1; i <= digits.length(); i++) {
double current = Double.parseDouble(digits.substring(0, i));
String remaining = digits.substring(i);
check(sum + previous, current, remaining, target, expr + " + " + current);
check(sum, previous * current, remaining, target, expr + " * " + current);
check(sum, previous / current, remaining, target, expr + " / " + current);
check(sum + previous, -current, remaining, target, expr + " - " + current);
}
}
}
static void f(String digits, double target) {
for (int i = 1; i <= digits.length(); i++) {
String current = digits.substring(0, i);
check(0, Double.parseDouble(current), digits.substring(i), target, current);
}
}
First, you need a method where you can input the expression
3141 * 5 / 9 * 26 / 5 * 3 - 5 * 8
and get the answer:
27182
Next, you need to create a tree structure. Your first and second levels are complete.
3
31, 3 + 1, 3 - 1, 3 * 1, 3 / 1
Your third level lacks a few expressions.
31 -> 314, 31 + 4, 31 - 4, 31 * 4, 31 / 4
3 + 1 -> 3 + 14, 3 + 1 + 4, 3 + 1 - 4, 3 + 1 * 4, 3 + 1 / 4
3 - 1 -> 3 - 14, 3 - 1 + 4, 3 - 1 - 4, 3 - 1 * 4, 3 - 1 / 4
3 * 1 -> 3 * 14, 3 * 1 + 4, 3 * 1 - 4, 3 * 1 * 4, 3 * 1 / 4
3 / 1 -> 3 / 14, 3 / 1 + 4, 3 / 1 - 4, 3 / 1 * 4, 3 / 1 / 4
You can stop adding leaves to a branch of the tree when a division yields a non integer.
As you can see, the number of leaves at each level of your tree is going to increase at a rapid rate.
For each leaf, you have to append the next value, the next value added, subtracted, multiplied, and divided. As a final example, here are 5 of the fourth level leaves:
3 * 1 + 4 -> 3 * 1 + 41, 3 * 1 + 4 + 1, 3 * 1 + 4 - 1, 3 * 1 + 4 * 1,
3 * 1 + 4 / 1
Your code has to generate 5 expression leaves for each leaf until you've used all of the input digits.
When you've used all of the input digits, check each leaf equation to see if it equals the value.
My Javascript implementation:
Will improve the code using web worker later on
// was not allowed to use eval , so this is my replacement for the eval function.
function evaluate(expr) {
return new Function('return '+expr)();
}
function calc(expr,input,target) {
if (input.length==1) {
// I'm not allowed to use eval, so I will use my function evaluate
//if (eval(expr+input)==target) console.log(expr+input+"="+target);
if (evaluate(expr+input)==target) document.body.innerHTML+=expr+input+"="+target+"<br>";
}
else {
for(var i=1;i<=input.length;i++) {
var left=input.substring(0,i);
var right=input.substring(i);
['+','-','*','/'].forEach(function(oper) {
calc(expr+left+oper,right,target);
},this);
}
}
};
function f(input,total) {
calc("",input,total);
}

How to trace a recursion?

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

Returns from Recursive methods

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;

Categories