This is a simple recursion program I have for a completion problem. I have retuped this on my phone so ignore and syntax errors or missing code.
Is there a specific reason I'm getting stack overflow errors for this specific algorithm?
public static int ulam( int x, int c) {
if(x==0)
return 1;
else if(x%2==0)
x=x/2;
else if(x%2==1)
x=x*2 +1;
return ulam(x, ++);
}
Your recursion goes too deep. Everytime you enter the function recursively it puts the parameters and the return value on the stack.
If you recurse too often, the stack overflows.
Heres what your function does for x == 7
x = 15
x = 30
x = 15
x = 30
... it will run infinitely and therefore overflow the stack
The following is not a valid Java syntax.
return ulam(x, ++);
Perhaps, as others have suggested, you'd like to fix that.
Related
I'm trying to write a Java program to calculate the square root of an integer x, without using in-built functions like Math.pow() . This is the approach I tried -
class Solution {
public int mySqrt(int x) {
if(x==0 || x==1)
return x;
// if(x>=2147395600)
// return 46340;
int i;
for(i=1 ; i*i<=x ; i++) {}
return i-1;
}
}
Without the commented part, I start getting errors if x is in the range 2147395600 <= x <= 2^31-1 (which is the upper limit of an int's value range in Java). For instance, for the input x=2147395600, the expected output is 46340 but the actual output is 289398. Why is this happening? Thanks to all in advance.
PS - I am aware there are other (better) methods to solve this problem, but I'd really like to know why this code behaves this way.
Since 46340 * 46340 = 2147395600, when i=46340, x=2147395600 and you reach the condition i*i<=x it evaluates to true since 2147395600 = 2147395600. So the loop counter will incremnet by 1 and in the next iteration we will get i=46341 and i * i will cause an overflow - 46341*46341 = -2147479015.
The loop condition will still be true, since -2147479015 <= 2147395600, and the loop will not stop.
You can replace the <= with =, and check for edge cases that may occur now.
I've ran the below code and I think it's correct. However, it just keeps returning stack overflow. When I run it in debug mode, I noticed somehow within the function x%y returns y instead of the remainder which is suppose to be 0. Can someone please help and see why this is?
public class test
{
public static void main (String [] args)
{
System.out.println(gcd(50,10));
}
static double gcd(double x, double y)
{
if (x > y)
{
return gcd(y, x);
}
else if (y <= x && x%y == 0)
{
return y;
}
else
{
return gcd(y, x%y);
}
}
}
Technically speaking, the implementation causes a stack overflow because for the arguments 50 and 10 the recursive calls reach the first and the last case alternatively, causing an infinite recursion. Apparently the algorithm for determining the greatest common divisor is implemented incorrectly; an elaborate presentation of it can be found here. That being said, it might not be a good idea to perform the calculations using the type double; I doubt that the division remainder operator % will behave as expected due to rounding.
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.
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.