Using recursion how can i keep the local variable updated [closed] - java

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Using recursion how can i keep the local variable updated till a condition is met. I have an instance below that explains why question very well. The count variable is a local variable and very time the method goes through the count is set to 0. I cannot move the count outside the method it has to be local variable not static or anything else.. The desired output should be (3 6)
public static int returnInt(int b) {
int count = 0;
if (b == 6) {
System.out.println(count + " " + b);
}
b += 2;
count++;
return returnInt(b);
}

Pass count as an additional parameter to the method:
public static int returnInt(int b, int count) {
... do some stuff to b, print something, check whether end-condition has been met ...
return returnInt(b, count + 1);
}
Then, call returnInt with an extra argument of 0 to start things off.

You cannot. Local variable is local by definition. It exists only in scope of current execution of the method.
BUT you have the following solutions.
The best one is to pass it as a parameter of your method (exactly as you do with other parameter b.
public static int returnInt(int b) {
return returnInt(b, 0)
}
private static int returnInt(int b, int count) {
// your code here.
}
If (for some strange reason) you cannot change the method signature you can put this variable into ThreadLocal. In this case even if several threads execute your method simultaneously your code stays thread safe.
Moving this variable to class level is the worst solution cause it is not thread safe and breaks encapsulation.

This function will overflow your stack. You must provide a way out when using recursion. And as for the variable count, you are redefining it back to 0 every time; it cannot be initialized inside the recursive function. Try passing it to your function as a parameter, and also providing a way out for your function.
public static int returnInt(int b,int count) {
if (b == 6) {
System.out.println(count + " " + b);
return b;
}
b+=2;
count++;
return returnInt(b);
}
the 'return b' line can be your way out...and you don'y necessarily have to return b... return whatever you need.

public static int returnInt(int b) {
return returnInt(b, 0);
}
private static int returnInt(int b, int count) {
if (b == 6) {
System.out.println(count + " " + b);
// My guess is you should be returning something here???
// Actually, this shouldn't be your exit point from the recursion because depending on the starting value of b, since you are always adding 2, it might never equal 6, so again you would get a StackoverflowException.
}
b += 2;
count++;
return returnInt(b, count);
}

In general, create returnIntInner(int b, boxed count), move the bulk of the logic to that, and call that from a "thin" version of returnInt. To box count the "old style" way is to pass the count as an int[1] array, so that it can be returned -- I've not studied up on the new Java reference parm syntax. But since your code is tail-recursive and doesn't need to access count after the recursive call, you can simply pass count as a regular parameter.

Related

Scope of variable instantiated inside a method - Java

Is this code safe in Java?
public class HelloWorld {
public static void main (String args[]) {
HelloWorld h = new HelloWorld();
int y = h.getNumber(5);
int z = h.getNumber (6);
if (y == 10)
System.out.println("true");
}
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
}
My co-worker says that int number will be placed on the stack and when getNumber returns it will be popped off and could potentially be overwritten.
Is the same code potentially unsafe in C?
The HelloWorld class has no fields, and is therefore immutable. You can call your getNumber(x) function as many times as you'd like, from any thread, using the same object, and it will always give the same result for the same argument.
Maybe your co-worker is recalling horror stories in C where you can have something like static int number, which "belongs" to the method and which would get overwritten. Or maybe she's thinking about "return by reference"; even if it were, you'd be referencing a brand-new object every time because number is newly instantiated for every method call.
Your coworker is correct, sort of, but they apparently misunderstand what is going on.
public int getNumber(int x) {
int number = 5;
number = number + x;
return number;
}
Yes the value of 5 + 5 or 5 + 6 will be placed on the stack, but there is no danger of them being overwritten, they will properly be placed into y or z.
I suspect the confusion is from C (this type code works fine in C as well), but for pointers instead of primitives. Returning a result of malloc from a function in C can be "challenging" if you don't do it right.

Java recursion class variable value is reset to 0

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.

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.

Java Recursion - Did I do this right? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
My job is to write a recursive version to this method. From what I understand Recursion is starting with a base call (if something then return) followed by an else which unwinds back to the original base. Like starting with a deck, adding on to the deck then removing cards from the deck until you are back to the original deck.
With that in mind here it is.
public static long fact(int n)
{
long result = 1;
while(n > 0)
{
result = result * n;
n = n - 1;
}
return result;
}
//my recursive version:
public static void recFact(int n)
{
if(n==0)
{
return n; // ir 0 it really doesn't matter right?
}
else
{
return recFact(n-1);
}
}
This is just an example test problem for an exam I have coming up, just want to make sure I have a handle on recursion. Did I do this right? If not what am I missing? please no answers in questions, just tell me what I did wrong and maybe some advice on better ways to understand it.
Thanks.
No, this recursive solution is not correct.
For every positive n, you're just return rectFact(n-1), which will recourse until you reach 0, at which point it will return. In other words, your function will always return 0. You're missing the part where you multiply the current n with rectFact(n-1). Additionally, note that 0! is 1, not 0:
public static int recFact(int n)
{
if(n==0)
{
return 1;
}
else
{
return n * recFact(n-1);
}
}
And finally, since the if clause returns, the else is somewhat redundant. This doesn't affect the method's correctness, of course, but IMHO the code looks cleaner without it:
public static int recFact(int n)
{
if(n==0)
{
return 1;
}
return n * recFact(n-1);
}
Your recursive version does no multiplication, and it will return zero for any input. So no, you didn't do it right.
But, the recursive version DOES recurse, so you have that going for you! To understand what's going wrong, walk through a very simple case.
Client calls recFact(3)
This will return to client recFact(2)
Which will return to above recFact(1)
Which will return to above recFact(0)
Which will return to above 0.
There are two major things going wrong:
Your base case is wrong (zero is too low)
You're not doing any multiplication
Good attitude about not wanting the solution handed to you! Hopefully these pointers wil help you figure it out.
EDIT: Apparently I misunderstood your grammar and you did want the solution.
Any recursive function needs three things:
The terminating condition: This tells the function when to stop calling itself. This is very important to avoid infinite recursion and avoid stack overflow exceptions.
The actual processing: You need to run the actual processing within each function. In your non recursive case, this was result = result * n. This is missing from your recursive version!
A collector/agggregator variable: You need some way to store the partial result of the recursive calls below you. So you need some way to return the result of recFact so that you can include it in processing higher up in the call chain. Note that you say return recFact(n - 1) but in the definition recFact returns void. That should probably be an int.
Based from your example you are missing the return type of your recFact which is int
Also recFact will always return 0 because you are not multiplying n each time to the recursion call of the method.
There are two ways to write recursive routines. One is the "standard" way that we all are taught. This is one entry point that must first check to see if the recursive chain is at an end (the escape clause). If so, it returns the "end of chain" value and ends the recursion. If not at the end, it performs whatever calculation it needs to get a partial value according to the level and then calls itself passing a value the next increment closer to the end of the chain.
private final int InitialValue = 15;
System.out.println( "Fact(" + InitialValue + ") = " + recFact( InitialValue ) );
public int recFact( int val ){
if( val < 2 ){
return 1;
}
else{
return recFact( val - 1 ) * val; // recursive call
}
}
//Output: "Fact(15) = 2004310016"
In regular recursion, a partial answer is maintained at each level which is used to supplement the answer from the next level. In the code above, the partial answer is val. When first called, this value is 15. It takes this value and multiplies it by the answer from Fact(14) to supply the complete answer to Fact(15). Fact(14) got its answer by multiplying 14 by the answer it got from Fact(13) and so on.
There is another type of recursion called tail recursion. This differs in that partial answers are passed to the next level instead of maintained at each level. This sounds complicated but in actuality, make the recursion process much simpler. Another difference is that there are two routines, one is non recursive and sets up the recursive routine. This is to maintain the standard API to users who only want to see (and should only have to see)
answer = routine( parameter );
The non-recursive routines provides this. It is also a convenient place to put one-time code such as error checking. Notice in the standard routine above, if the user passed in -15 instead of 15, the routine could bomb out. That means that in production code, such a test must be made. But this test will be performed every time the routine is entered which means the test will be made needlessly for all but the very first time. Also, as this must return an integer value, it cannot handle an initial value greater than 19 as that will result in a value that will overflow the 32-bit integer container.
public static final int MaxFactorialSeq = 20;
private final int InitialValue = 15;
System.out.println( "Fact(" + InitialValue + ") = " + recFact( InitialValue ) );
public int recFact( int value ){
if( value < 0 || value > MaxFactorialSeq ){
throw new IllegalArgumentException(
"Factorial sequence value " + value + " is out of range." );
}
return recFact( value, 1 ); // initial invocation
}
private int recFact( int val, int acc ){
if( val < 2 ){
return acc;
}
else{
return recFact( val - 1, acc * val ); // recursive call
}
}
//Output: "Fact(15) = 2004310016"
Notice the public entry point contains range checking code. This is executed only once and the recursive routine does not have to make this check. It then calls the recursive version with an initial "seed" of 1.
The recursive routine, as before, checks to see if it is at the end of the chain. If so, it returns, not 1 as before, but the accumulator which at this point has the complete answer. The call chain then just rewinds back to the initial entry point in the non-recursive routine. There are no further calculations to be made as the answer is calculated on the way down rather than on the way up.
If you walk though it, the answer with standard recursion was reached by the sequence 15*14*13*...*2*1. With tail recursion, the answer was reached by the sequence 1*15*14*...*3*2. The final answer is, of course, the same. However, in my test with an initial value of 15, the standard recursion method took an average of 0.044 msecs and the tail recursion method took an average of 0.030 msecs. However, almost all that time difference is accounted for by the fact that I have the bounds checking in my standard recursion routine. Without it, the timing is much closer (0.036 to 0.030) but, of course, then you don't have error checking.
Not all recursive routines can use tail recursion. But then, not all recursive routines should be. It is a truism that any recursive function can be written using a loop. And generally should be. But a Factorial function like the ones above can never exceed 19 levels so they can be added to the lucky few.
The problem with recursion is that to understand recursion you must first understand recursion.
A recursive function is a function which calls itself, or calls a function which ultimately calls the first function again.
You have the recursion part right, since your function calls itself, and you have an "escape" clause so you don't get infinite recursion (a reason for the function not to call itself).
What you are lacking from your example though is the actual operation you are performing.
Also, instead of passing a counter, you need to pass your counter and the value you are multiplying, and then you need to return said multiplied value.
public static long recFact(int n, long val)
{
if(n==1)
{
return val;
}
else
{
return recFact(n-1, val) * n;
}
}

Custom functions in Processing Language

doing some uni work on 'Processing' Programming language (a form of java).
So my question is 'Write a function called twoNumbers(int a,int b) which takes in two parameters a and b. If a is greater than b, then the two numbers are added together and the string 'the sum of a and b is sum' is displayed in the console window, where a and b and the sum are the values of a, b and their sum. Finally, the function should return the sum.'
..soo here is my attempt at the code, if I put (int a,int b) after the customer function, it just says that my other int a = number, is a duplicate, which is true, but im not sure how I am ment to give a and b a number without it thinking its a duplicate? Should I be putting it out of a void setup tag? as im unsure if this would then cause too many { brackets...
/* Question 1 */
int twoNumbers(){
int a = 30;
int b = 20;
if (a > b) {println(a+b);}
println("The sum of a and b is sum");
int sum;
sum = a+b;
println(sum);
}
Any help would be massively helpful in getting this and the other questions done :)
Thanks!!
Also your function is not returning a value, which will give you an error. It looks like you are confusing things. Either declare it a void or return a value of declared type (that last is what your assignment calls for). Either way a function, or a method, needs to be called to execute, and you are not calling it! So the code inside your the function is not being run!!
The following:
void imAMethod()
{
println("hello");
}
It is a valid method, but will do nothing, you need to call it, like:
imAMethod();// calling your method
void imAMethod()
{
println("hello");
}
But this won't work also, will give you the error "It looks like you're mixing "active" and "static" modes". Thats because to use a function in Processing you need to have at least a setup() method in the sketch, so:
void setup()
{
imAMethod();
}//end of setup
void imAMethod()
{
println("hello");
}
will work as expected.
But you need a function, so as Jesper pointed you will have to do something like:
int a = 30; // those are global variables to pass to your function
int b = 20;
void setup()// this is a builtin basic Processing method
{
//call your function
println("The sum of " + a + " and " + b + " is "+ twoNumbers(a, b));
}
int twoNumbers(int a, int b)
{
//do your math and tests here
return result;
}
There is another thing not clear in the assignment. A function must return something, so it is not clear what the function should return if a is not greater than b. You will have to handle this case, or compiler will complain. You may want to move this test out of the function to make things easier, like:
if (a < b)
println("The sum of " + a + " and " + b + " is "+ twoNumbers(a, b));//call your function
else
println(a + " is smaller than " + b);
and in the function just do the sum. But this may be not what the assignment requires... Anyway you will need to return something even if a is not greater than b. Note that the printing to console can be done inside the function also.
Hummm, re reading the assignment a think what is expected is: Aways return the sum, and just print if a is greater than b, which makes more sense and is easier, something like:
int twoNUmbers(int a, int b)
{
if (a < b){/*print the string*/}
return a + b;
}
Just a note for jlordo. In Processing.org you don't have a main, or better, it is transparent/hidden from user. Processing is like a "dialect" of java. So the code above would run as it is. There are two basic builtin functions: setup() and draw(). If the user do not use none of them the IDE will warps it in a setup() function, that will call the main() somewhere else. It will run once. Draw() instead loops forever.
'Write a function called twoNumbers(int a,int b) which takes in two parameters a and b.
That's not what your code looks like. Your method twoNumbers doesn't take two parameters a and b. Your code should start like this (exactly as mentioned in the assignment):
int twoNumbers(int a, int b) {
Remove the next two lines, int a = 30; and int b = 20;. Those lines declare two local variables named a and b. You should use the a and b that are passed in as parameters instead.
This also looks wrong:
if (a > b) {println(a+b);}
println("The sum of a and b is sum");
Carefully look at what the assignment says:
If a is greater than b, then the two numbers are added together and the string 'the sum of a and b is sum' is displayed in the console window, where a and b and the sum are the values of a, b and their sum.
That's not what your code is doing. Take it step by step, carefully think about what is meant in the assignment.

Categories

Resources