Java recursion class variable value is reset to 0 - java

I was trying to implement the coin change problem using recursion. I have written the following code and am facing a problem with the static class variable. 'answer' is a class variable and i am trying to add the return value to it in the loop. This works fine within the while loop but after the while loop ends the answer is reset to 0;
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
Below is all the code that I have written. You can copy and run it to check.
import java.util.ArrayList;
import java.util.Collections;
public class CoinChangeHashMap {
static int answer = 0;
public static void main(String[] args) {
int[] array = new int[] { 7, 3, 2 };
ArrayList<Integer> input = new ArrayList<Integer>();
getList(array, input);
findCombinations(12, input);
System.out.println(answer);
}
private static void getList(int[] array, ArrayList<Integer> input) {
for (int i : array) {
input.add(i);
}
}
public static int findCombinations(int sum, ArrayList<Integer> denominations) {
if (denominations.size() == 1) {
if (sum % denominations.get(0) == 0) {
return 1;
}
return 0;
}
int i = 0;
int currentCoin = denominations.get(0);
while (i * currentCoin <= sum) {
System.out.println("inside while; answer is " + answer);
answer = answer
+ findCombinations(
sum - i * currentCoin,
new ArrayList<Integer>(denominations.subList(1,
denominations.size())));
i++;
}
return 0;
}}
**The output that I get is 0. but the expected output is 4. While debugging the output that I got is **
inside while; answer is 0
inside while; answer is 0
inside while; answer is 1
inside while; answer is 1
inside while; answer is 2
inside while; answer is 2
inside while; answer is 0
inside while; answer is 0
inside while; answer is 0
0
Any Help is appreciated.

The problem is related to your odd code structure, in which you convey the outcome of your recursive call sometimes by modifying static variable answer, and sometimes via the method's return value.
If you analyzed the problem more closely, you would discover that it is not upon exit from the loop that the partial results are lost, but rather some time after return from the method. Therefore, consider carefully the way you update the answer:
answer = answer + findCombinations( /* ... */ );
At the top-most level of your recursion, answer is initially 0. When Java evaluates the above expression, it evaluates first the left operand and then the right operand, then it adds them. That is, it evaluates answer, getting the result 0, before it performs the recursive call. The value of answer may be updated in the course of the recursive call, but those changes come too late. Only the bottom-most level of the recursion ever returns a value different from zero, so if the recursive call itself recurses at least one level deeper then it will return zero. In that case, the sum is computed as 0 + 0, and assigned to answer, clobbering any update the method performed.
You could resolve the problem by swapping the order of the operands in your sum, but it would be better, and not much harder, to get rid of the static variable altogether. Use a local variable within the method to accumulate results, and in all cases convey the total back to the caller via the method's return value.

Related

Euclid's algorithm shows wrong conclusion

Homework of mine is to create and Euclid's algorithm in java. The task binds me to use both while-loop and if statement. Futhermore - if statement has to be placed inside while-loop.
During this task i faced already infinity-loop problem, somehow manage to get pass it. Now my Euclid's algorithm is giving multiple answers (instead of one) and futhermore they are wrong...
I have searched a couple of topics over here, but none of answers shown in there gave me an answer. I tried to rewrite whole code, and also diffrent conditions for while-loop and if statement.
import java.lang.*;
class EuklidesAlgorithm {
public static void main (String[] args) throws java.lang.Exception{
int a = 25648;
int b = 15468;
while (a % b != 0 ){
int modulo = a % b;
if (modulo == 0){
break;
}else {
modulo = a % b;
System.out.println(" Checking for GCD");
a = b;
b = modulo;
}
System.out.println(" Number " + b + " is GDC of numbers(" + a + "," + b + ").");
}
}
}
I would like it to give a single answer what is GCD for a and b.
First of all the condition :
modulo==0
will alaways be false inside the loop...
and you dont have to change variable prices inside the loop and you also don't have to print answers in every loop so...
the if statement is probably goind to be used to check if any of those two numbers is 0 or if the result is 0 but you can do both

What causes this recursive function to crash compared to another nearly identical one? [duplicate]

This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 7 years ago.
This causes a Stack Overflow error. I just need help explaining why this one crashes compared to the correct one which is similar. I have used the debugger, but it is still unclear to me.
public static void main(String[] args) {
countForwards(5);
}
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num--);
}
System.out.print(num + " ");
}
I know this is the solution but I don't understand why it is different
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num - 1);
}
System.out.print(num + " ");
}
countForwards(num--) passes the original value of num to the recursive call, which means the recursion never ends.
countForwards(--num) would allow the recursion to end.
After seeing all the traffic this question got, I thought it would be worth it to expand the answer a little.
As paxdiablo commented, even though countForwards(--num) allows the recursion to terminate, it behaves differently than countForwards(num-1).
Both variants would cause the following series of recursive calls :
countForwards(5)
countForwards(4)
countForwards(3)
countForwards(2)
countForwards(1)
countForwards(0)
countForwards(-1)
but they will output a different series of numbers when the recursion unwinds :
num - 1
-- num
-1
-1
0
-1
1
0
2
1
3
2
4
3
5
4
The reason for the difference is that num-1 doesn't change the value of num while --num decrements num.
num-- uses a postfix operator -- which means that original value i.e. num is passed and its value is decremented after it is passed.
The interesting thing about a postfix operator i.e. the one we are using in this example is that operation is performed and then the value is incremented or decremented. Please refer to official documentation about operators in java
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
Post-Decrement
Post-Decrement takes the form variable-name operator. This tells the compiler to first use the original value and afterawrds decrement it, so if we have something like this:
for (int i = 10; i > 0; i--)
{
System.out.println(i);
}
The output will be as follows
1: 10
2: 9
3: 8
4: 7
5: 6
6: 5
7: 4
8: 3
9: 2
10: 1
Pre-Decrement
Pre-Decrement takes the form operator variable-name and is used when you want to decrement before you use the value. The same code above would terminate at 0 instead of 1. This is because the function decremented the value before it used the value.
How does this apply to recursive calls?
Each recursive call is it's own stack, so when you pass num-- to the recursive function, you're literally passing the original value of num, and when the child call terminates (in this case never) the parent call will then decrement num. Since you don't have another base case which correctly terminates the call, it results in infinite recursion.
Actually it is happening due to post decrement operator in the method.
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num--);
}
System.out.print(num + " ");
}
Now when the function is calling the countForwards again it is always taking value of num as 5 due to post decrement in the method, please try to change as pre-decrement
public static void countForwards( int num ) {
if (num >= 0){
countForwards(--num);
}
System.out.print(num + " ");
}
This will be work because value is first decremented and then that value is using method.
as function is calling again and these are primitive and stores in the stack. Thats why it is showing stack overflow.
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num - 1);
}
System.out.print(num + " ");
}
This is working because this is an expression which try to solve first itself and then the function can use the value of that expression. I hope it will answer your question.

Working of Return statement in a method in Java

I am trying to understand the working of return statement in JAVA.
My doubt is if inside a method with a Non void return type, I have a decision block which also has a return statement of its own, Still I have to return some value .
For understanding here is a sample code I have written :-
public int bunnyEars(int bunnies) {
//int count=0;
if (bunnies >=1) {
count = count + 2;
bunnyEars(bunnies -1);
return count1;
}
return count2 ;
}
In the mentioned code I just want to return the no. of bunnies which I am being able to do from inside the bunnyEars method count1. But still JAVA wont allow to have a non-void method without a return type which is totally understood and I have to add count2 return also. Now I am suspecting that I am having a conceptual understanding failure here. Kindly let me know if I am missing something? Kindly let me know If I am missing some more info here.
[Edited] Full code:
public class Test5 {
//public int ears=1;
public int count=0;
public int bunnyEars(int bunnies) {
//int count=0;
if (bunnies >=1) {
count = count + 2;
bunnyEars(bunnies -1);
return count;
}
return count ;
}
public static void main(String args[]){
Test5 test5= new Test5();
System.out.println(test5.bunnyEars(90));
}
}
Yes you need to return count2 which should be zero. Which means if there are no bunnies then there are no ears. So which returning you should be returning some value irrespective of the conditional block.
So in this case
return count1;
represents the number of ears if the bunnies are represent, while
return count2;
represents the number of ears when there are no bunnies, which should be 0.
I hope that gives you some clarification
I think your conceptual misunderstanding lies with understanding the flow of the program.
Supposed you were to use this method by calling:
bunnyEars(2)
Then, once you enter the method, the first thing the program does is check if 3 >= 1. Since this is true, you proceed into the code inside the {..} (called a 'block'). Inside this block, you increment count by 2. I am assuming count is defined elsewhere in the class, but suppose the current value for count is 10. Then, the new value of count will be 12.
After this, the program executes the line:
bunnyEars(bunnies - 1)
Which translates to:
bunnyEars(1)
Now, basically, you are calling the same method again, but passing in 1 instead of 2.
Once again, the program checks to see that 1 >= 1, which is true. So it goes into the
if-block which, again, increments count by 2. So now, count = 14. Then it calls the
same method again but this time passing in 0.
bunnyEars(0)
Since 0 >= 1 evaluates to false, you the program skips the if-block and continues
execution after the block. So know, you are in the method bunnyEars(), but you have
completely skipped over your "return" statement. But, alas, bunnyEars MUST return an int.
So this is why you must have a return after the block. In your case, bunnyEars(0) returns count2 and the program-execution returns to where you called bunnyEars(0).
Read up on recursive calls. The basic idea of a recursive method is that, inside the recursive method, you must have some case that terminates the recursion (otherwise you will loop forever).
For example, the following code will go on forever:
public int sum(int in)
{
return in + sum(in - 1);
}
This will keep going on forever, because sum(1) will call sum(0) which calls sum(-1).
So, I must have a condition that terminates the recursion:
public int sum(int in)
{
if(in == 0) return 0;
return in + sum(in - 1);
}
Now, I have a terminating-case. So if I call sum(1), it will call sum(0) which returns 0. So my result is 1 + 0 = 1.
Similarily,
sum(2) = 2 + sum(1) = 2 + 1 + sum(0) = 2 + 1 + 0
sum(3) = 3 + sum(2) = 3 + 2 + sum(1) = 3 + 2 + 1 + sum(0) = 3 + 2 + 1 + 0 = 6
Hope this helps!
So as I understand it, your question is why you still need to return count2 if you return count1. The answer is basically 'what happens if you don't enter the if block?'. In that case, without return count2, you wouldn't have a return value, which is what Java is complaining about. If you really don't want two return statements, you could probably do something like:
public int bunnyEars(int bunnies) {
int count=0;
if (bunnies >=1) {
count = count + 2;
bunnyEars(bunnies -1);
}
return count ;
}
On a side note, this and the code you posted in your question won't work for regression purposes, but the one in your comment does, and there it looks like you have a static variable for count, in which case you could set the return type to void and just print count.

Problem with recursive backtracking - Sudoku Solving Example

recently I've been trying to teach myself a bit of recursion to understand the process better. While I understand basic recursion techniques, I still struggle quite a bit with the idea of recursive backtracking. In order to help this, I've attempted to program a method that solves a sudoku solver when given a 2D array and and two ints, r and c, which are meant to represent the current column and row.
I have everything set up properly I believe, yet I can't quite figure out how to handle the "unraveling", or what happens after my initial method calls reach the eventual base case.
As of right now, when I run this method, it just returns a board that's empty, (unless there was previously a value there before, in which case it remains unchanged). I feel like the "board[r][c] = 0" that I have at the end of the method might have something to do with that.
The method "digitsValid" corresponds to a method that checks to make sure the current location on the board is a valid move within the row, column, and 3x3 subgrid.
Any help would be much appreciated.
private boolean sudokuSolver(int[][] board, int r, int c) {
if(c > 8) {
c = 0;
r = r + 1;
}
if(r > 8) {
return true;
}
if(board[r][c] != 0) {
sudokuSolver(board, r, c + 1);
} else {
for(int i = 1; i <= 9; i++) {
if(digitsValid(board, r, c)) {
board[r][c] = i;
if(sudokuSolver(board, r, c + 1)) {
return true;
}
}
}
}
board[r][c] = 0;
return false;
}
I think your original assessment is correct. Recursive methods sound confusing but think of them like this:
public class RecursiveTest{
public static void main(String[] args){
int x = 5;
recursiveMethod(x);
}
public static void recursiveMethod(int i){
System.out.println("Method just started for i = " + i);
if(i > 0)
recursiveMethod(i - 1);
System.out.println("Method just ended for i = " + i);
}
}
Yields the following output:
Method just started for i = 5
Method just started for i = 4
Method just started for i = 3
Method just started for i = 2
Method just started for i = 1
Method just started for i = 0
Method just ended for i = 0
Method just ended for i = 1
Method just ended for i = 2
Method just ended for i = 3
Method just ended for i = 4
Method just ended for i = 5
Explanation
A recursive method is not all that different from any other method. It executes some code, at some point calls a method, runs that method and then continues running the rest of the code and finishes where any other method would finish.
The only difference is that method call is a call to itself. This would work the same as if you had copy-pasted that same method 5 times and named it all something different and then "daisy chained" them together.
In the example above, the original value is 5, it prints out that it started the for i=5, then ran the same method with the value of 4. Printed that, then ran 3 etc. Once it reached the final value where i = 0 the if statement failed and therefore it stopped the recursive calls. The method we are currently in (i = 0) finishes by writing Method just ended for i = 0 then it returns to the calling method when i = 1 and back tracks the same way it went in.
Your Code
I'm not quite sure what you have going on here. Does your example work? I'd like to see the isValid() method, but the following code you have:
for(int i = 1; i <= 9; i++) { // Runs the following code 9 times.
if(digitsValid(board, r, c)) { // if true once, true every time
board[r][c] = i;
if(sudokuSolver(board, r, c + 1)) { // this is a totally separate method
return true;
}
}
}
Your loop runs 9 times. The if statement following it never changes. The values within are not edited within the loop, so if it evaluates to true when i = 1 then it's going to evaluate to true on all 9 iterations of the for loop. This means the value at board[r][c] is going to end on 9.
From the looks of it, the only way this will ever return false, is if there is an invalid digit already stored in the array at the time of calling the method.

Recursion output ambiguity

Ok so i am just learning recursion and i am confused on one point.
This is the code
public class RecursiveDemo {
public static void showRecursion (int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
public static void main(String[] args){
showRecursion(2);
}
}
The output i am getting is :
Entering method. num = 2
Entering method. num = 1
Leaving method. num = 1
Leaving method. num = 2
My question is why am i getting the output "Leaving method. num = 2". Shouldn't it stop at "Leaving method. num = 1" since num has already reached 1?
Once the original invocation of this method leaves the if statement, it passes to System.out.println("Leaving method. num = " + num);. Since you invoked the message originally with value 2, 2 is the value of num for this part of the code.
Your code runs like this (pseudocode):
Start First Call
if statement
Start Second call
Skips if statement
Print from Second Call
End of Second Call
End of if Statement
Print From First Call
End of First Call
It looks like you have a fundamental misunderstanding of recursion.
When you call your method with (num-1) as arguments, the parent call (the first call, in this case), retains the value num as its argument, which is 2, in this case.
So let's comment out the line below
//showRecursion(num - 1);
What would you get? It must be
Entering method. num = 2
Leaving method. num = 2
And if you uncomment the line above. You should get the one you had.
No.
main will call showRecursion(2), which in turn will call showRecursion(1) (so you get two "Entering" messages). At which point, the condition will fail, so no more recursion occurs. So now the program simply begins returning from each function call in turn, printing both of the "Leaving" messages.
It's because the initial call to showRecursion(2) hasn't finished yet.
Consider the following:
public static void showFirstRecursion (int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showSecondRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
public static void showSecondRecursion (int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showThirdRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
// I won't bother showing an implementation for showThirdRecursion, because it won't be called.
public static void main(String[] args){
showFirstRecursion(2);
}
No problem here, right? You'd expect to see the first method entered, second entered, (third not entered because num == 0), second left, first left.
There is really nothing special about recursion. It's just making a function call that happens to be calling the function that the call is a part of. A recursive call behaves, conceptually, in all respects like any other function call. The trick is the design of a recursive algorithm, i.e., coming up with a reason why you'd want to call the same function you're already in.
The other answers already cover the specific question, but here is some information on using a debugger. This tutorial is for Eclipse, but pretty much tells you what you need to know for any visual debugger.
The basics are pretty straightforward, and it would be well worth your time to at least learn how to step through the code. A debugger is an invaluable tool for quickly verifying the logic of your program, and is far easier than scattering print statements everywhere.
Try "showRecursion(5);".
[Answer: This is recursion. There's more than one copy of the variable "num" in memory. "num" is a parameter; it's not a field, and it's not static.]
So what I understood was
with every method call, Stack is getting populated ie. 2,1
but when i>1 doesn't matches it returns/breaks the call and control is given to the system.out.println line, that prints the value starting from the top of stack ie 1,2

Categories

Resources