Understanding Return f(n-1) + 5. - java

I am learning recursion need a better explanation of the following code. I have most of it down, but not I am sort of confused on the last part of the function where it says return f(n-1) + 5. I got 32 for f(7) which is correct, and that prints out at the very last, but I am still a little fuzzy and was wondering if anyone would give me a better explanation.
The output.
I know that once n = 1 by f(n-1) n being 7 at first, then (7-1) = 6 and so on until it gets to 1, which returns a value of 2, but this where I get sort of lost. What about the + 5? 2 + 5 = 7, 7 + 5 = 12,... 27 + 5 = 32. How does this tie to the f(n-1) + 5
public class scratch {
public static void main(String[] args) {
System.out.println(f(7));
}
static int f(int n) {
System.out.println("f(" + n + ")");
if (n <= 1)
return 2;
else
return f(n - 1) + 5;
}
}

What is the problem? When your n becomes 1 it returns 2 to n = 2 and then this n = 2 returns 2 + 5 to n = 3 and so on.
For Example, Consider f(7):
n = 7, f(6) + 5
n = 6, f(5) + 5
n = 5, f(4) + 5
n = 4, f(3) + 5
n = 3, f(2) + 5
n = 2, f(1) + 5
n = 1, 2
As you see, f(1) will return 2 to f(2) which will return 2 + 5 to f(3) and so on.

If a program says int x = f(1);, then it calls the method f. Since the argument is 1, this just returns 2.
If a program says int x = f(2);, it calls the method f. The argument is 2, so it executes this line:
return f(n - 1) + 5;
which calls the method f again, with argument 1. As I noted in the first paragraph, when you call f with argument 1, it returns 2, so the above evaluates to
return 2 + 5;
which is 7.
If a program says int x = f(3);, it calls the method f. The argument is 3, so it executes this line:
return f(n - 1) + 5;
which calls the method f again, with argument 2. As I noted earlier, when you call f with argument 1, it returns 7, so the above evaluates to
return 7 + 5;
which is 12. And so on.
I think you basically do understand what's going on; hopefully, breaking it down like this will help eliminate whatever doubts you still have.

Related

What is the Time and Space Complexity of LeetCode 241. Different Ways to Add Parentheses?

I am trying to understand what is time complexity of leetcode 241. Different ways to add parentheses. I have used memoization technique. My friend was asked in Google coding round, he couldn't give correct time and space complexity. I found same problem in Leetcode.
Problem:
Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.
Example 1:
Input: "2-1-1"
Output: [0, 2]
Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2
Example 2:
Input: "2 * 3 - 4 * 5"
Output: [-34, -14, -10, -10, 10]
Explanation:
(2*(3-(4*5))) = -34
((23)-(45)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
Code:
import java.util.*;
class Solution {
Map<String, List<Integer>> map = new HashMap<>();
public List<Integer> diffWaysToCompute(String input) {
if(map.containsKey(input)) {
return map.get(input);
}
List<Integer> result = new ArrayList<>();
int length = input.length();
for(int i = 0; i< length; i++) {
char character = input.charAt(i);
if(isOperator(character)) {
String part1 = input.substring(0, i);
String part2 = input.substring(i + 1);
List<Integer> part1Result = diffWaysToCompute(part1);
List<Integer> part2Result = diffWaysToCompute(part2);
computeAndStoreResult(input, result, i, part1Result, part2Result);
}
}
//store in map...
map.put(input, result);
//this is when only one input is present.
// input 3 ==> nothing is added in result so add 3 ...
if(result.size() == 0) {
result.add(Integer.valueOf(input));
}
return result;
}
private boolean isOperator(char character) {
return character == '-' || character == '*' || character == '+';
}
private void computeAndStoreResult(String input, List<Integer> result, int i, List<Integer> part1Result, List<Integer> part2Result) {
for(Integer p1 : part1Result) {
for(Integer p2 : part2Result) {
int c= 0;
switch (input.charAt(i)) {
case '+':
c = p1+p2;
break;
case '-':
c = p1-p2;
break;
case '*':
c = p1*p2;
break;
}
result.add(c);
}
}
}
}
I have research on many sites could not find good explanation
This is how recursive tree looks like: Techinque used is divide and conquer with memoization.
Some useful links that I found.
https://www.cnblogs.com/yrbbest/p/5006196.html
https://just4once.gitbooks.io/leetcode-notes/content/leetcode/divide-and-conquer/241-different-ways-to-add-parentheses.html
Observation
If an expression consists of a single number, then there's 1 way to place parentheses.
If there's only 1 math operator in an expression, then there's only 1 way to place parentheses to obtain a relevant result. For example, for 3 + 4 it's (3 + 4).
If there are 2 math operators in an expression, then there are 2 ways to place parentheses. For example, for 3 + 4 - 2, the method will split the expression by + into 3 and 4 - 2, and then by - into 3 + 4 and 2. So, it's 2 ways.
If there are 3 math operators in an expression, then it's 5 results. For example, 1 + 2 - 3 * 4 can be split into 1 and 2 - 3 * 4, 1 + 2 and 3 * 4, 1 + 2 - 3 and 4. As we've learned from 2) and 3), the number of ways is 2 + 1 + 2 = 5` ways.
If there are 4 math operators in an expression, then it's 14 results. For example, 1 + 2 - 3 * 4 + 5 can be split into 1 and 2 - 3 * 4 + 5, 1 + 2 and 3 * 4 + 5, 1 + 2 - 3 and 4 + 5, 1 + 2 - 3 * 4 and 5. As we've learned from 2), 3) and 4) the number of ways is 5 + 2 + 2 + 5 = 14 ways correspondingly.
If the sequence is continued then it will be 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, .... As you can see, it grows exponentially.
Such sequence of numbers has a name and is called Catalan numbers.
Application for your algorithm
As you may have already realised, your algorithm will become exponential even after you obtain results for your left and right subexpressions split by the first math operator.
So, if there are 10 math operators, then after computing the results for the first configuration (expression is split by the first math operator) their number will be 4862.
So, not only is your time complexity exponential, but also your space complexity since you save all the results in a list.

Get the consecutive numbers whose sum matches with given number

I was going through a simple program that takes a number and finds the number of occurrences of consecutive numbers that matches with given number.
For example:
if input is 15, then the consecutive numbers that sum upto 15 are:
1,2,3,4,5
4,5,6
7,8
So the answer is 3 as we have 3 possibilities here.
When I was looking for a solution I found out below answer:
static long process(long input) {
long count = 0;
for (long j = 2; j < input/ 2; j++) {
long temp = (j * (j + 1)) / 2;
if (temp > input) {
break;
}
if ((input- temp) % j == 0) {
count++;
}
}
return count;
}
I am not able to understand how this solves the requirement because this program is using some formula which I am not able to understand properly, below are my doubts:
The for loop starts from 2, what is the reason for this?
long temp = (j * (j + 1)) / 2; What does this logic indicates? How is this helpful to solving the problem?
if ((num - temp) % j == 0) Also what does this indicate?
Please help me in understanding this solution.
I will try to explain this as simple as possible.
If input is 15, then the consecutive numbers that sum upto 15 are:
{1,2,3,4,5} -> 5 numbers
{4,5,6} -> 3 numbers
{7,8} -> 2 numbers
At worst case, this must be less than the Sum of 1st n natural numbers = (n*(n+1) /2.
So for a number 15, there can never be a combination of 6 consecutive numbers summing up to 15 as the sum of 1st 6 numbers =21 which is greater than 15.
Calculate temp: This is (j*(j+1))/2.
Take an example. Let input = 15. Let j =2.
temp = 2*3/2 = 3; #Meaning 1+2 =3
For a 2-number pair, let the 2 terms be 'a+1' and 'a+2'.(Because we know that the numbers are consecutive.)
Now, according to the question, the sum must add up to the number.
This means 2a+3 =15;
And if (15-3) is divisible by 2, 'a' can be found. a=6 -> a+1=7 and a+2=8
Similarly, let a+1 ,a+2 and a+3
a + 1 + a + 2 + a + 3 = 15
3a + 6 = 15
(15-6) must be divisible by 3.
Finally, for 5 consecutive numbers a+1,a+2,a+3,a+4,a+5 , we have
5a + 15 = 15;
(15-15) must be divisible by 5.
So, the count will be changed for j =2,3 and 5 when the input is 15
If the loop were to start from 1, then we would be counting 1 number set too -> {15} which is not needed
To summarize:
1) The for loop starts from 2, what is the reason for this?
We are not worried about 1-number set here.
2) long temp = (j * (j + 1)) / 2; What does this logic indicates? How is this helpful to solving the problem?
This is because of the sum of 1st n natural numbers property as I have
explained the above by taking a+1 and a+2 as 2 consecutive
numbers.
3) if ((num - temp) % j == 0) Also what does this indicate?
This indicates the logic that the input subtracted from the sum of 1st
j natural numbers must be divisible by j.
We need to find all as and ns, that for given b the following is true:
a + (a + 1) + (a + 2) + ... (a + (n - 1)) = b
The left side is an arithmetic progression and can be written as:
(a + (n - 1) / 2) * n = b (*)
To find the limit value of n, we know, that a > 0, so:
(1 + (n - 1) / 2) * n = n(n + 1) / 2 <= b
n(n + 1) <= 2b
n^2 + n + 1/4 <= 2b + 1/4
(n + 1/2)^2 <= 2b + 1/4
n <= sqrt(2b + 1/4) - 1/2
Now we can rewrite (*) to get formula for a:
a = b / n - (n - 1) / 2
Example for b = 15 and n = 3:
15 / 3 - (3 - 1) / 2 = 4 => 4 + 5 + 6 = 15
And now the code:
double b = 15;
for (double n = 2; n <= Math.ceil(Math.sqrt(2 * b + .25) - .5); n++) {
double candidate = b / n - (n - 1) / 2;
if (candidate == (int) candidate) {
System.out.println("" + candidate + IntStream.range(1, (int) n).mapToObj(i -> " + " + (candidate + i)).reduce((s1, s2) -> s1 + s2).get() + " = " + b);
}
}
The result is:
7.0 + 8.0 = 15.0
4.0 + 5.0 + 6.0 = 15.0
1.0 + 2.0 + 3.0 + 4.0 + 5.0 = 15.0
We are looking for consecutive numbers that sum up to the given number.
It's quite obvious that there could be at most one series with a given length, so basically we are looking for those values witch could be the length of such a series.
variable 'j' is the tested length. It starts from 2 because the series must be at least 2 long.
variable 'temp' is the sum of a arithmetic progression from 1 to 'j'.
If there is a proper series then let X the first element. In this case 'input' = j*(X-1) + temp.
(So if temp> input then we finished)
At the last line it checks if there is an integer solution of the equation. If there is, then increase the counter, because there is a series with j element which is a solution.
Actually the solution is wrong, because it won't find solution if input = 3. (It will terminate immediately.) the cycle should be:
for(long j=2;;j++)
The other condition terminates the cycle faster anyway.
NB: loop is starting from 2 because=> (1*(1+1))/2 == 1, which doesn't make sense, i.e, it doesn't effect on the progress;
let, k = 21;
so loop will iterate upto (k/2) => 10 times;
temp = (j*(j+1))/2 => which is, 3 when j =2, 6 when j = 3, and so on (it calculates sum of N natural numbers)
temp > k => will break the loop because, we don't need to iterate the loop when we got 'sum' which is more than 'K'
((k-temp)%j) == 0 => it is basically true when the input subtracted from the sum of first j natural numbers are be divisible by j, if so then increment the count to get total numbers of such equation!
public static long process(long input) {
long count = 0, rest_of_sum;
for (long length = 2; length < input / 2; length++) {
long partial_sum = (length * (length + 1)) / 2;
if (partial_sum > input) {
break;
}
rest_of_sum = input - partial_sum
if (rest_of_sum % length == 0)
count++;
}
return count;
}
input - given input number here it is 15
length - consecutive numbers length this is at-least 2 at max input/2
partial_sum = sum of numbers from 1 to length (which is a*(a+1)/2 for 1 to a numbers) assume this is a partial sequence
rest_of_sum = indicates the balance left in input
if rest of sum is multiple of length meaning is that we can add (rest_of_sum/length) to our partial sequence
lets call (rest_of_sum/length) as k
this only means we can build a sequence here that sums up to our input number
starting with (k+1) , (k+2), ... (k+length)
this can validated now
(k+1) + (k+2) + ... (k+length)
we can reduce this as k+k+k+.. length times + (1+2+3..length)
can be reduced as => k* length + partial_sum
can be reduced as => input (since we verified this now)
So idea here is to increment count every-time we find a length which satisfies this case here
If you put this tweak in it may fix code. I have not extensively tested it. It's an odd one but it puts the code through an extra iteration to fix the early miscalculations. Even 1/20000 would work! Had this been done with floats that got rounded down and 1 added to them I think that would have worked too:
for (long j = 2; j < input+ (1/2); j++) {
In essence you need to only know one formula:
The sum of the numbers m..n (or m to n) (and where n>m in code)
This is ((n-m+1)*(n+m))/2
As I have commented already the code in the original question was bugged.
See here.
Trying feeding it 3. That has 1 occurrence of the consecutive numbers 1,2. It yields 0.
Or 5. That has 2,3 - should yield 1 too - gives 0.
Or 6. This has 1,2,3 - should yield 1 too - gives 0.
In your original code, temp or (j * (j + 1)) / 2 represented the sum of the numbers 1 to j.
1 2 3 4 5
5 4 3 2 1
=======
6 6 6 6 6 => (5 x 6) /2 => 30/2 => 15
As I have shown in the code below - use System.out.println(); to spew out debugging info.
If you want to perfect it make sure m and n's upper limits are half i, and i+1 respectively, rounding down if odd. e.g: (i=15 -> m=7 & n=8)
The code:
class Playground {
private static class CountRes {
String ranges;
long count;
CountRes(String ranges, long count) {
this.ranges = ranges;
this.count = count;
}
String getRanges() {
return this.ranges;
}
long getCount() {
return this.count;
}
}
static long sumMtoN(long m, long n) {
return ((n-m+1)* (n+m))/2;
}
static Playground.CountRes countConsecutiveSums(long i, boolean d) {
long count = 0;
StringBuilder res = new StringBuilder("[");
for (long m = 1; m< 10; m++) {
for (long n = m+1; n<=10; n++) {
long r = Playground.sumMtoN(m,n);
if (d) {
System.out.println(String.format("%d..%d %d",m,n, r));
}
if (i == r) {
count++;
StringBuilder s = new StringBuilder(String.format("[%d..%d], ",m,n));
res.append(s);
}
}
}
if (res.length() > 2) {
res = new StringBuilder(res.substring(0,res.length()-2));
}
res.append("]");
return new CountRes(res.toString(), count);
}
public static void main(String[ ] args) {
Playground.CountRes o = countConsecutiveSums(3, true);
for (long i=3; i<=15; i++) {
o = Playground.countConsecutiveSums(i,false);
System.out.println(String.format("i: %d Count: %d Instances: %s", i, o.getCount(), o.getRanges()));
}
}
}
You can try running it here
The output:
1..2 3
1..3 6
1..4 10
1..5 15
1..6 21
1..7 28
1..8 36
1..9 45
1..10 55
2..3 5
2..4 9
2..5 14
2..6 20
2..7 27
2..8 35
2..9 44
2..10 54
3..4 7
3..5 12
3..6 18
3..7 25
3..8 33
3..9 42
3..10 52
4..5 9
4..6 15
4..7 22
4..8 30
4..9 39
4..10 49
5..6 11
5..7 18
5..8 26
5..9 35
5..10 45
6..7 13
6..8 21
6..9 30
6..10 40
7..8 15
7..9 24
7..10 34
8..9 17
8..10 27
9..10 19
i: 3 Count: 1 Instances: [[1..2]]
i: 4 Count: 0 Instances: []
i: 5 Count: 1 Instances: [[2..3]]
i: 6 Count: 1 Instances: [[1..3]]
i: 7 Count: 1 Instances: [[3..4]]
i: 8 Count: 0 Instances: []
i: 9 Count: 2 Instances: [[2..4], [4..5]]
i: 10 Count: 1 Instances: [[1..4]]
i: 11 Count: 1 Instances: [[5..6]]
i: 12 Count: 1 Instances: [[3..5]]
i: 13 Count: 1 Instances: [[6..7]]
i: 14 Count: 1 Instances: [[2..5]]
i: 15 Count: 3 Instances: [[1..5], [4..6], [7..8]]

Addition in field with finite int elements?

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;

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);
}

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