Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
public static boolean sum_rec(int[] A, int n, int k) {
return addition(A, n, k, 0);
} // end sum_rec
private static boolean addition(int[] A, int n, int k, int i) {
if (k == A[i] + A[n - 1 - i]) {
return true;
}
else if (n == 1){
return false;
}
else
return addition(A, n, k, i++);
}
Hi, I am getting stackoverflow error whenever I try to run the following code. It returns true if there are any two numbers in array that sum up to a value k but I cant seem to find the error. Any help will be appreciated. Also what is the running time of this?
You need a base case that will end the recursion (return false) in the case that
k == A[i]+A[n-1-i]
is never true.
n == 1 is not that base case since n doesn't change during the recursion ... a base case that depends on the variable that changes during recursion
There are multiple problems with your code. One that hasn't been pointed out yet is that you think you're calling the method recursively by adding 1 to the last parameter, but you're not. This line:
return addition(A, n, k, i++);
has a post-increment operator. This means that it will add 1 to i but it will use the old value of i as the parameter. So it's the same as:
int oldValueOfI = i;
i = i + 1;
return addition(A, n, k, oldValueOfI);
You can see that you're calling the method recursively with the exact same values that it was called last time, so of course it will recurse infinitely. Although I wouldn't use recursion for this program, if you really want to, change the call to
return addition(A, n, k, i + 1);
You're not going to use i afterwards, so you don't need to change the value. (Note that each recursive call has its own i variable; the variable is not shared between the calls. So incrementing i will not have any impact on the i used by the next recursive call, the previous recursive call, or any other recursive call.)
Also note that this will not solve your problem, but making this change might help you figure out what to do next when your program starts blowing up on a different exception.
Related
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 1 year ago.
Improve this question
Recently in class, there was a recursion function that returned an array as either being true or false (sorted or not). However, I had trouble understanding it. The function is:
int[] array = { 3, 5, 2, 57, 8, 20 };
int start=0;
boolean sorted = sorted( array, start, array.length );
System.out.print( "array: ");
for ( int i=0 ; i<array.length ; ++i ) System.out.print( array[i] + " " );
if (sorted) System.out.println(" is sorted" );
else System.out.println( "is not sorted" );
static boolean sorted(int array[], int i, int count ) {
if (count == 1 || count == 0) return true;
if (array[count - 1] < array[count - 2]) return false;
return sorted(array, i-1, --count);
}
What is happening in the method and how is the recursion working? What does the variable count do if there is already an integer i? Why must it be equal to 0(or null) and 1? Why are the variables different for when you initialize "sorted" in the main method and for the sorted method? I believe some of the additional questions I asked may be redundant or unnecessary if I knew how the whole method worked. I would really appreciate your help!
First of all, welcome to the forum! :) Indubitably, recursion is something that's really difficult to come to grips with, but if you have learned about stack - as a part of the memory - you can understand recursion more easily. This article might appear useful in investigating what exactly happens in these types of algorithms.
The code might not be written in Java, but the syntax itself will be fairly understandable. I suggest you skip the memoization part - since it is more advanced and you can learn it later -, but the factorial code and the image are really self-explanatory.
You could also practice and write these algorithms and I agree: debugging is excessively useful if you don't understand something.
Finally, let me add some practical pieces of advice in the future for coding in Java:
Auto-format your code (the hotkeys are different in every major IDE's, but they definitely exist)
Avoid C-style coding when declaring arrays:
instead of
int array[]
, Java devs tend to do it in the following way:
int[] array
(Fun fact about multidimensional arrays: int[][] array, int array[][] and int[] array[] (!) work too.)
Last, but not least, do not miss curly braces also if there is only one statement in that particular block of code.
These are only coding conventions, though that code is syntactically alright, as you might have already seen it.
Happy coding!
The sorted method could just be:
static boolean sorted(int array[], int count) {
if (count == 1 || count == 0) {
// If the array has no elements or if it just has a single element,
// then it means that the array is sorted.
return true;
}
if (array[count - 1] < array[count - 2]) {
// If an element is less than the previous element,
// then the array is not sorted.
return false;
}
// check rest of the array.
return sorted(array, count-1);
}
I would suggest you to debug through the whole code so that you could get a better picture of what is happening.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
import java.util.*;
class towers{
public static void main(String args[])
{
honoi('A','B','C',(long)1,n);
}
static int disk_no(long i,int n) // to find the next disk to move
{
if(i%2!=0)
return 1;
else
{
int j;
long k;
for(j=2;j<=n;j++)
for(k=0;k<Math.pow(2,n-j);k++)
if(i==(long)Math.pow(2,(long)j-1)*((2*k)+1))
{
System.out.println("returning :"+j);
return j;
}
return 0;
}
}
static void honoi(char x,char y,char z,long i,int n)
{
if(i<Math.pow(2,n))
{
switch((int)i%2)
{
case 0:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+z+" to "+y);
honoi(x,y,z,++i,n);break;
default:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+x+" to "+y);
honoi(y,z,x,++i,n);
}
}
}}
I read n value from user as number of disks ofcourse I skipped it here
I thought that the problem is with
disk_no()
function if not mention the logical errors in the code if any
The problem is that your code throws a StackOverflowError.
Essentially, your honoi method prints out all the moves necessary to solve the Towers of Hanoi puzzle with n disks from step i onwards. It does this by figuring out what is necessary for move i and then calling itself with i replaced with i + 1 and optionally with x, y and z switched around.
The problem arises because your method calls itself. Each time Java calls your honoi method, it needs to store where to return to when executing the method finishes. It stores these return locations on a 'stack'. When a method returns, Java removes the last of these locations from the top of the stack and resumes running your program from this location. There is only a limited amount of space for the 'stack' used for these return locations. If this stack grows too large, Java will throw a StackOverflowError.
If you run your program with a large number of disks, your code will require too much space to store return locations, because your method calls itself too many times before it returns. Your honoi method only returns once all of the moves have been displayed.
To avoid the stack overflow, I modified your honoi method to the following, which uses a loop instead of calling itself. i is now a loop variable, so I've removed i as a method parameter. You will need to remove the (long)1 from your call to honoi in main():
static void honoi(char x,char y,char z,int n)
{
for (long i = 1; i < Math.pow(2,n); ++i)
{
switch((int)i%2)
{
case 0:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+z+" to "+y);
break;
default:System.out.println("STEP "+i+" :\tMove disk "+(long)disk_no(i,n)+" from pole "+x+" to "+y);
char temp = x;
x = y;
y = z;
z = temp;
}
}
}
The four lines from char temp = x; onwards swap around x, y, and z, as your recursive version of this method called itself with the x, y and z arguments switched around in the default case.
I don't know if you originally wrote this program in another language (e.g. a functional language such as Haskell) which supports tail recursion optimization. If a language supports this optimization, then it will be able to detect whether a method ends with a call to the same method, and if so, jump back to the start of the method using a kind of 'goto'. Your code would seem to benefit from this kind of optimization: if tail recursion optimization was supported in Java, your code would quite possibly run without an error. However, that's not likely to happen in Java.
I already searched everywhere for a solution for my problem, but didn't get one. So what I'm trying to do ist use recursion to find out whats a passed integer variable's base to the power of the passed exponent. So for example 3² is 9. My solution really looks like what I found in these forums, but it constantly gives me a stack overflow error. Here is what I have so far.(To make it easier, I tried it with the ints directly not using scanner to test my recursion) Any idea?
public class Power {
public static int exp(int x,int n) {
n = 3;
x = 2;
if (x == 0) {
return 1;
}
else {
return n * exp(n,x-1);
}
}
public static void main(String[] args) {
System.out.println(exp(2,3));
}
}
Well, you've got three problems.
First, inside of the method, you're reassigning x and n. So, regardless of what you pass in, x is always 2, and n is always 3. This is the main cause of your infinite recursion - as far as the method is concerned, those values never update. Remove those assignments from your code.
Next, your base case is incorrect - you want to stop when n == 0. Change your if statement to reflect that.
Third, your recursive step is wrong. You want to call your next method with a reduction to n, not to x. It should read return x * exp(x, n-1); instead.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am preparing for an exam next week, and I decided to look for some exam questions online for better preparation.
I came across this question and the answer is c. But I really want to know how or the step by step process to answer to answer a question like this. The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method? Whenever I get to a question like this is their anything important I should breakdown first?
private int[] myStuff;
/** Precondition : myStuff contains int values in no particular order.
/*/
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--)
{
if (myStuff[k] < num)
{
return k;
}
}
return -1;
}
Which of the following best describes the contents of myStuff after the
following statement has been executed?
int m = mystery(n);
(a) All values in positions 0 through m are less than n.
(b) All values in positions m+1 through myStuff.length-1 are
less than n.
(c) All values in positions m+1 through myStuff.length-1 are
greater than or equal to n.
(d) The smallest value is at position m.
(e) The largest value that is smaller than n is at position m.
See this page to understand a method syntax
http://www.tutorialspoint.com/java/java_methods.htm
int m = mystery(n); means this method going to return int value and you are assigning that value to a int variable m. So your final result is m. the loop will run from the array's end position to 0. loop will break down when array's current position value is less than your parameter n. on that point it will return the loop's current position. s o now m=current loop position. If all the values of the loop is greater than n it will return -1 because if condition always fails.
Place the sample code into a Java IDE such as Eclipse, Netbeans or IntelliJ and then step through the code in the debugger in one of those environments.
Given that you are starting out I will give you the remainder of the code that you need to make this compile and run
public class MysteriousAlright {
private int[] myStuff;
public int mystery(int num)
{
for (int k = myStuff.length - 1; k >= 0; k--) {
if (myStuff[k] < num) {
return k;
}
}
return -1;
}
public static void main(String[] args) {
MysteriousAlright ma = new MysteriousAlright();
ma.setMyStuff(new int[] {4,5,6,7});
int m = ma.mystery(5);
System.out.println("I called ma.mystery(5) and now m is set to " + m);
m = ma.mystery(3);
System.out.println("I called ma.mystery(3) and now m is set to " + m);
m = ma.mystery(12);
System.out.println("I called ma.mystery(12) and now m is set to " + m);
}
public void setMyStuff(int[] myStuff) {
this.myStuff = myStuff;
}
}
You then need to learn how to use the debugger and/or write simple Unit Tests.
Stepping through the code a line at a time and watching the values of the variables change will help you in this learning context.
Here are two strategies that you can use to breakdown nonsense code like that which you have sadly encountered in this "educational" context.
Black Box examination Strategy
Temporarily ignore the logic in the mystery function, we treat the function as a black box that we cannot see into.
Look at what data gets passed in, what data is returned.
So for the member function called mystery we have
What goes in? : int num
What gets returned : an int, so a whole number.
There are two places where data is returned.
Sometimes it returns k
Sometimes it returns -1
Now we move on.
White Box examination Strategy
As the code is poorly written, a black box examination is insufficient to interpret its purpose.
A white box reading takes examines the member function's internal logic (In this case, pretty much the for loop)
The for loop visits every element in the array called myStuff, starting at the end of the array
k is the number that tracks the position of the visited element of the array. (Note we count down from the end of the array to 0)
If the number stored at the visited element is less than num (which is passed in) then return the position of that element..
If none of elements of the array are less than num then return -1
So mystery reports on the first position of the element in the array (starting from the end of the array) where num is bigger than that element.
do you understand what a method is ?
this is pretty basic, the method mystery receives an int as a parameter and returns an int when you call it.
meaning, the variable m will be assigned the value that returns from the method mystery after you call it with n which is an int of some value.
"The part where I got stuck is trying to logically understand how a int m = mystery(n); How can a number equal a method?"
A method may or may not return a value. One that doesn't return a value has a return type of void. A method can return a primitive value (like in your case int) or an object of any class. The name of the return type can be any of the eight primitive types defined in Java, the name of any class, or an interface.
If a method doesn't return a value, you can't assign the result of that method to a variable.
If a method returns a value, the calling method may or may not bother to store the returned value from a method in a variable.
I am trying to learn recursion in Java and have an array that takes in continuous input until the Scanner reads in a 0.
From there I have a method that (attempts) to calculate the number of positive integers in the array using recursion. This is the first recursive function I have ever written and I keep getting a stackoverflow error.
I have read tutorials and I still can't wrap my head around the basic understanding of recursion.
public class reuncF {
private static int start = 0;
private static int end = 98;
public static void main(String[] args) {
input = input.nextDouble();
list[i] = numInput;
computeSumPositive(numList, count);
}
}
return positives += solve(numbers, count++);
}
}
You forgot to stop your recursion!
There has to be some case where computeSumPositive returns without calling itself again. Otherwise it'll just keep going forever, never getting back to you.
If you did it with a loop, the loop would look like this:
int positives = 0;
for (int i = 0; i < numList.length; ++i) {
if (numList[i] > 0) {
positives++;
}
}
To do that recursively, you just find out what are the variables used in the loop. They are i, numList and positives.
computeSumPositive(int i, double[] numList, int positives)
Then we take a look at what the loop does. First, it checks whether we went too far,
so our recursive function should do that too. It'll have to return instead of just falling through like the loop does. And obviously, it must return the result:
{
if (! (i < numList.length))
return positives;
The loop then does the test and maybe increments positives, so the recursive function should also do that:
if (numList[i] > 0) {
positives++;
}
At the end of the loop, i is updated:
i++;
The loop just starts over, but the recursive function will have to call itself. Of course, we want it to use the new value of i and positives, but fortunately we updated those, so now we can just do:
return computeSumPositives (i, numList, positives);
}
The tricky bit is that the values i, numList, and are local to each call. Each invocation of computeSumPositives can see only the arguments it were given. If it changes them, none of the other invocation can see that change.
EDIT: So if we, for reasons we can only speculate about, wanted desperately for computeSumPositive to take only 2 parameters, we would have to "split up" positives across each invocation. Each invocation knows whether or not its number was positive or not; all we have to do is add them. Then it looks like this:
computeSumPositive(int i, double[] numList)
{
if (! (i < numList.length))
return 0; // I didn't find any at index i
if (numList[i] > 0) {
// Theres one I found + however many my later
// invocations will find.
return 1 + computeSumPositive (i+1, numList);
} else {
// I didn't find any, but my later invocations might.
return computeSumPositive (i+1, numList);
}
}
I find it helpful, when dealing with recursion, to figure out the termination case first.
It looks like you are treating 'count' as an index. So you could check if your at the last index in the array, if so and if the value is positive return a 1, if the value is non-positive return a 0 - dont recurse anymore.
If your not at the last index, and the value is positive return a 1 + the recursive function call, or if the value is non-positive just continue to recurse.
This will still cause a stack overflow for large arrays.
The value of count++ is the same as the value of count; the program uses the value and then increments it. But the result is that computeSumPositive keeps calling itself with the same value of count, which leads to infinite recursion. Note that each time computeSumPositive calls another computeSumPositive, each call has its own copy of the parameters (like count) and the local variables; so incrementing one computeSumPositive's copy of count has no effect on the value of count used by other recursive calls.
Change count++ to count + 1, and also add a way to halt the recursion. (At some point, you will be calling computeSumPositive to look at zero integers, and at that point, it should just return 0 and not call itself. You need to think about: how do you test whether you've reached that point?)