What is the reason of the StackOverflowError? I was trying it for a while but still can't get why it happens, and how to fix it.
The formula used in the code is a requirement.
public static long fib(long n){
if(n == 1 || n == 2)
return 1;
else if(n > 2 && n%2 == 0)//even
return fib((n/2+1)*(n/2+1)) - fib((n/2-1)*(n/2-1));
else //odd
return fib(((n+1)/2)*((n+1)/2)) + fib(((n-1)/2)*((n-1)/2));
}
public static void main(String[] args){
for(int i = 1; i <= 10; i++)
System.out.println(fib(i)+" ");
}
Not really sure what you are trying to achieve with your method, but by just adding some System.out.println to your code you can see what you are getting in each recursive call. For what I see your "odd" call is getting into an infinite loop and that is why you got that StackOverflowError error, Typically this is caused when your recursive functions doesn't have the correct termination condition, that is to say, it ends up calling itself forever.
For the way you start your code and the "fib" method name, it looks like you are trying to perform Fibonacci, which can be done in a simpler way:
public static int getFibonacci(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
return getFibonacci(n - 1) + getFibonacci(n - 2);
}
Related
I have a code to reverse an integer, but it does not work, can't seem to find the bug.
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
} else if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}
Sometimes it is easier and/or better to rewrite instead of debugging.
Write or think of your algorithm in pseudocode where each high level step is then broken down into more pseudocode. Your conditions seem strange and therefore hard to debug.
It is best not to embed a print directly into the heart of a loop. Rather, build a string and return it. Let the caller print a string.
System.out.println (reverseInt (12345));
public static String reverseInt (anInt) {
Initialize a StringBuffer with an empty string.
while (anInt > 0) {
Get last digit by modulo 10 and put in StringBuffer.
Prepend digit in StringBuffer.
Chop off last digit by doing integer divide.
}
return StringBuffer's .toString ();
}
An alternate algorithm would call reverseInt recursively to build an ever growing string.
if and else if both works together in a sequence from top to down
if(true) { execute } else if() { done execute even if condition is true } else { done execute}
if(false) else if(check condition) { if true execute other wise go to next condition}
So on..
in your case, this is going to be solution
public static void test(int N) {
int enable_print = N % 10;
while (N > 0) {
if (enable_print == 0 && N % 10 != 0) {
enable_print = 1;
}
if (enable_print == 1) {
System.out.print(N % 10);
}
N = N / 10;
}
}
The task is to implement a program which counts how many different Sums of Primes there are for a given number sumtoBreak.
The Method primeSum should subtract all possible primes currprime from the number sumtoBreak until the sumtoBreak becomes zero and then return (in sum) a one for each possibilty. To account for all possibilities, in each recession step, it calls itself
with sumtoBreak - currprime plus
calls itself with the nextPrime.
My Problem is that java won't return anything unless the sumtoBreak is zero right at the beginning.
Would be glad for any advice!
Here's the code (I know that the parenthesis in the code with the nested if statements are redundant, but I just wanted to make sure, that's not the problem):
Here's the fixed code:
public class PrimeSum {
public static boolean isPrime(int primecandidate) {
int count = 0;
for (int i = 2; i <= primecandidate / 2; i++) {
if (primecandidate % i == 0)
count++;
}
if (count == 0)
return true;
else
return false;
}
public static int nextPrime(int currprime) {
int j = currprime + 1;
while (!isPrime(j))
j++;
return j;
}
public static int primeSum(int sumtoBreak, int currprime) {
if (sumtoBreak == 0) {
return 1;
} else {
if (sumtoBreak < 0 || currprime > sumtoBreak) {
return 0;
} else {
return primeSum(sumtoBreak, nextPrime(currprime)) + primeSum(sumtoBreak - currprime, currprime);
}
}
}
public static void main(String[] args) {
System.out.println(primeSum(Integer.parseInt(args[0]), 2));
}
}
This doesn't answer your question, but corrects an error in your isPrime Method and computes the result much faster:
private static boolean isPrime(final int primecandidate) {
if ( primecandidate < 2) { // 0 & 1 are NOT Prime
return false;
}
if ((primecandidate & 0x1) == 0) { // Even is NOT Prime...
return primecandidate == 2; // ...except for 2 (and 0).
}
for (int i = 2, iMax = (int) Math.sqrt(primecandidate); i <= iMax; i++) {
if (primecandidate % i == 0) {
return false;
}
}
return true;
}
Note the following:
the final argument primecandidate is marked final
it corrects the result for 0 & 1 to false
the method is marked private
the iMax is Sqrt(primecandidate) & not primecandidate / 2
iMax is calculated once, instead of every iteration
I use a strategy I call "if you're done, be done."
Meaning: don't set a flag (in your case count), just get out!
Please note also, there is an apache commons Math3 function...
org.apache.commons.math3.primes.Primes.isPrime(j)
It is significantly slower for smallish values (<= Short.MAX_VALUE)
It is somewhat faster for largeish values (ca. Integer.MAX_VALUE)
There is also a BigInteger.isProbablePrime(...) function, but my Benchmark suggests it is rather slow.
I hope this helps a little?
Some things you might have missed:
in a function, a return statement terminates (break) the function immediatly. So in
if(...) { return ...; }
else {...}
→ else is redundant, as if the condition is true, the function is already terminated (break)
Something like a==0 has a boolean value (true or false). So
if(count==0) { return false; }
else { return true;}
can be shortened to return count!=0;
I recommend to always use braces, because something like if(i==0) ++i; break;, means if(i==0) {++i;}. break; will be called in any case.
public static boolean
isPrime(int n)
{
if(n==0 || n==1) { return false; }
for(int i= 2; i <= n/2; ++i)
{
if(n%i == 0) { return false; } //we know, n is not a prime,
//so function can break here
}
return true; //since for all values of i, the function did not break,
//n is a prime
}
I wish you a lot of motivation to code for the future!
So, I am studying java, and as a first exercise I decided to write two small and composable functions, namely a fibbonacci and a factorial function, which have a common implementation detail, however I received a stack overflow exception when I tried to separate their common part into a separate function. Any tips on what am I doing wrong?
public class BaseFunctions{
static Integer factorial(Integer num) {
return factorial(comComponent(num)-1)*num;
}
static Integer fibbonacci(Integer num) {
return fibbonacci(comComponent(num)-1) + fibbonacci(comComponent(num)-2);
}
static Integer comComponent(Integer num) {
if(num == 1 || num == 0) {
return 1;
}else if(num < 0){
throw new ArithmeticException("Num must be > 0");
}else return num;
}
}
When you reach num = 0, comComponent will return 1, calling your function with num = 0 again, thus getting stuck in an infinite loop.
A recursive function must have an exit point (which must be checked first before any recursive call), if not this leads to Stack Overflow.
What you do is leave the function without that exit point, be delegating (or so you think) this functionality to comComponent().
But take a look at the code inside factorial():
return factorial(comComponent(num)-1)*num;
Why should it ever stop? There is no return statement without a recursive call.
So your logic is wrong.
Drop comComponent() and stick to the traditional way:
static Integer factorial(Integer num) {
if (num == 1 || num == 0)
return 1;
else if (num < 0)
throw new ArithmeticException("Num must be > 0");
else
return factorial(num - 1) * num;
}
static Integer fibbonacci(Integer num) {
if (num == 1 || num == 0)
return 1;
else if (num < 0)
throw new ArithmeticException("Num must be > 0");
else
return fibbonacci(num - 1) + fibbonacci(num - 2);
}
As you can see both functions have an exit point:
if (num == 1 || num == 0)
return 1;
I am writing one method which having int prototype. But the method is showing error in editor by saying that Add return statement where return statement is already present. When I am adding another return it is working fine. I am writing in eclipse.
Here is my code :
private static int nextPrime(int n) {
if(n % 2 == 0)
n++;
for(; !isPrime(n); n+=2)
return n;
return n;
}
What is going wrong here. Thanks for help.
I think the problem is that your for loop has no body. Try giving it one:
private static int nextPrime(int n) {
if(n % 2 == 0)
n++;
for(; !isPrime(n); n+=2) { }
return n;
}
But really I think a for loop is the wrong kind of loop for this. Instead, you might want to use a while loop:
private static int nextPrime(int n) {
if (n % 2 == 0)
n++;
while (!isPrime(n)) {
n += 2;
}
return n;
}
The first return is in the scope of the loop, then the compiler force you to put one at the end of the function as you must ensure that on every path a return is made, alas the compiler cannot prove by itself that you always enter the loop...
It seems that your loop lack of a body...
public static int divisor(int m, int n) {
if (m == 0 || n == 0) {
return m+n;
} else {
return divisor(n, m%n);
}
}
It's giving me wrong answers for some input(I don't know which as they don't reveal which input they use for test case) in the amazon.interviewstreet.com
Also why this implementation keeps giving me stackoverflow(again no idea for which inputs)
public static int divisor(int m, int n) {
if(m == 0 || n == 0) {
return m+n;
} else if (m > n) {
return divisor(n, m%n);
} else {
return divisor(m, n%m);
}
}
Please let me know what am I missing. I'm new to programming and am still a beginner.
I think first one is a code for a programming contest. If so be careful with your data types. May be 'int' is not enough to hold the inputs. Try 'long' instead.
(and this will work only if your algorithm is correct.)
I think
return(m, n%m);
should be
return divisor(m, n%m);
Maybe invalid handling of negative values of n and m?
Read e.g. this: Best way to make Java's modulus behave like it should with negative numbers?
for the second part what is
return(m, n%m);
Is this code get compiled ?
use :
public static int divisor(int m, int n) {
if(m == 0 || n == 0)
return m+n;
else if(m>n)
return divisor(n, m%n);
else
return divisor(m, n%m);}
First,
return(m, n%m)
definitely does not compile, I suppose it was meant to be
return divisor(m, n%m);
Second, I guess what is wrong in the second snippet is handling of negative numbers.
Because A and B have the same GCD as -A and -B, I would add
m = Math.abs(m);
n = Math.abs(n);
to the beginning of the method
For the second part :
Also why this implementation keeps giving me stackoverflow(again no idea for which inputs)?
Try this input set :
5
3 1 16 5 10
It will give you the stackoverflow error. For your given code in pastebin.
Why ?
If the input is '1' there will be this problem.
edit your code part like below and see the out put for input (1 1).
public static int divisor(int m, int n) {
System.out.println("### "+m+" "+n);
if (m == 0 || n == 0) {
return m + n;
} else if (m > n) {
return divisor(n, m % n);
} else {
return divisor(m, n % m);
}
}
in some point out put will be like this :
.
.
### 1 1134903170
### 1 0
### 1 1836311903
### 1 0
### 1 -1323752223
### -1323752223 1
### -1323752223 1
### -1323752223 1
.
.
because in your code the function calling is like below.
public static int divFib(int num) {
int i = 1, j = 2, temp;
while (divisor(num, j) == 1) {
temp = j;
j = j + i;
i = temp;
}
return j;
}
divisor(num, j) will be called like divisor(1, 2) then below part will execute
else {
return divisor(m, n % m);
}
the calling will be like divisor(1,0) because n%m = 2%1 =0
then '1' will be return as (m+n = 1).
then while (divisor(num, j) == 1){} will execute again and 'j' will be get increased. But 'num' is '1'. the same thing happens again and again. resulting 'j' to be a huge number and eventually it will assigned a negative number. (I think you know why its happening).
The thing is this will not ever stopped. so the stack will be overflowed due to huge number of function calls.
I think this is a quite clear explanation and if you have any doubt please ask.
(Sorry i mistakenly post the answer here.)