I am trying to print Fibonacci series using recursion and my code is not ending the recursion . Can you tell me if i missed something.I think the second recursion is going into infinite loop and i am not able to figure out why it is happening
class Main
{
public static void main (String[] args)
{
int k=7;
int x=0,y=1;
fib(x,y,k,0);
return;
}
public static void fib(int x,int y,int k,int cnt)
{
int z;
if(cnt>k)
return;
if(cnt<=k)
{
z=x+y;
x=y;
y=z;
System.out.println("value is"+z);
fib(x,y,k,cnt++);
}
}
}
You don't seem to understand the concept of Fibonacci Number. Please read the wikipedia article. Following is the code for this function.
public static int fib(int n)
{
if(n == 0 || n == 1)
return n;
return fib(n-1) + fib(n-2);
}
The issue is the post-increment in:
fib(x,y,k,cnt++);
This passes the original value of cnt to the recursive call, and then increments it.
If you print the value of cnt at the start of fib(), you'll see that it is always zero.
One easy fix is to change that call to
fib(x,y,k,cnt+1);
Also, your numbering of Fibonacci numbers is a bit odd (I'd say that the seventh number is 8 and your code thinks it's 34).
Finally, I may be worth noting that the second if is unnecessary.
Related
I have to write a java code for the 'sieve of eratosthenes' algorithm to print out primes up to a given max value on the console but I'm not allowed to use arrays. Our professor told us it is possible to do only with the help of loops.
So I thought a lot and googled a lot about this topic and couldn't find an answer. I dont think it's possible at all because you have store the information which digits are already crossed out somewhere.
my code until now:
public static void main(String[] args) {
int n = 100;
int mark = 2;
System.out.print("Primes from 1 to "+n+": 2, ");
for (int i = 2; i <= n; i++) {
if(i % mark != 0){
System.out.print(i+", ");
mark = i;
}
}
}
-> So, i'm not allowed to do the "i % mark != 0" command with numbers which are multiples of the numbers i already printed but how am i supposed to make that clear without an array where i can delete numbers on indexes?
BUT if there is a solution I would be glad if someone could share it with me! :)
The solution can be in other programming languages, i can translate it to java myself if its possible.
Thank you in advance and best regards
Update: Thank you very much all of you, i really appreciate your help but I don't think it can be done with the basic structures. All the algorithms i have seen yet which print out primes by using basic structures are no sieve of eratosthenes. :(
The Sieve is about remembering the primes you found already. As far as I know there is no way to do this without arrays or lists and only with loops.
I checked some of the examples at RosettaCode at random and did not find one without an array and only loops.
If you add Classes and Methods as options you can come up with a recursive design:
public class Sieve
{
private int current;
private int max;
private Sieve parent;
public Sieve(int current, int max, Sieve parent )
{
this.current = current;
this.max = max;
this.parent = parent;
}
public static void main(String[] args)
{
int n = 100;
System.out.print("Primes from 1 to " + n + ":\n");
printPrimes(n);
}
private static void printPrimes(int i)
{
new Sieve(2,i,null).start();
}
private void start()
{
if(current <2 || max <2)
{
return;
}
if(this.current > max)
{
parent.print();
return;
}
for(int i = this.current+1;current<=max+1;i++)
{
if(this.testPrime(i))
{
new Sieve(i,this.max,this).start();
return;
}
}
}
private boolean testPrime(int i)
{
if(i%this.current != 0)
{
if(this.parent == null)
{
return true;
}
else
{
return this.parent.testPrime(i);
}
}
return false;
}
private void print()
{
if(this.parent != null)
{
this.parent.print();
}
System.out.print(" "+this.current);
}
}
This removes the array but uses Objects to store the Prime (each Sieve holds one prime)
I'm taking back what I said earlier. Here it is, the "sieve" without arrays, in Haskell:
sieve limit = [n | n <- [2..limit], null [i | i <- [2..n-1], j <- [0,i..n], j==n]]
It is a forgetful sieve, and it is very very inefficient. Uses only additions, and integer comparisons. The list comprehensions in it can be re-coded as loops, in an imperative language. Or to put it differently, it moves counts like a sieve would, but without marking anything, and thus uses no arrays.
Of course whether you'd consider it a "true" sieve or not depends on what is your definition of a sieve. This one constantly recreates and abandons them. Or you could say it reimplements the rem function. Which is the same thing to say, actually, and goes to the essence of why the sieve suddenly becomes so efficient when reuse - via arrays usually - becomes possible.
EDIT: Got it working. Still not sure what the weird issue was, but I think it had to do with the fact that I had a loop and recursion.
I don't fully understand the question. but you don't need both, a while loop and recursion. Recursion alone is sufficient here. Use a simple if statement to stop recursion when the number is fully printed.
Note that recursion simplifies putting the digits in the right order here -- with a while loop, you'd need to reverse them somehow...
public static void printInBinary (int num) {
int div = num % 2;
int rem = num / 2;
if (rem > 0) {
printInBinary(rem);
}
System.out.print(div);
}
Your while loop is continuously going because your num-- isn't in the loop, so the number never changes.
public static void printInBinary (int num)
{
int div = (Integer)num%2;
int rem = (Integer)num/2;
while (num >= 1)
{
System.out.print(div);
printInBinary(rem);
num--;//Moved here
}
//removed from here
}
The method evenSquares takes a single int parameter, n, (for example, 10000), and then prints all of the (positive) even perfect squares less than n, each on a separate line.
Notice that evenSquares has a void return type, since all it does is print integers to the console. Be sure to use the println method to print each entry of your output.
Example: if n = 40, your code should print:
4
16
36
(Hint: your method should be built around a for loop with a test component that asks if the square of the control variable (say, k) is < n. Thus, the loop should terminate as soon as k*k equals or exceeds n.)
I'm given this
public void evenSquares(int n) {
public class Squares {
public static void main(String[] args) {
evenSquares(40);
}
public static void evenSquares(int n) {
for(int sq, k=2; (sq = k*k) <= n ; k += 2){
System.out.println(sq);
}
}
}
I am trying to create a method that will generate a Fibonacci sequence based on user input and calculated to the tenth number, all through recursion. (Learning recursion right now, this is one exercise).
Here is my attempted code, which I am currently struggling to make work:
//being run with fibonacci(10, 10);
//Start being the number the sequence starts with
public static int fibonacci(int start, int times)
{
if(times > 0)
{
int result = fibonacci(start - 1, times - 1) + fibonacci(start - 2, times - 1);
sequence += result;
return result;
}
System.out.println(sequence);
return start;
}
This, however, returns a large amount (I think about 40,000 numbers taking approximately 10 seconds to run to completion). Also all the numbers appear to be negative, definitely not what my aim was.
Now, on to identifying the problem: I believe the problem is that the method is calling itself twice more every single time it is called, adding up to the large amount. However, I can't think of a way around this seeing as I am trying to do it through recursion each time and I have no choice but to call it again.
As for why it is negative, I haven't a clue. I thought I was using the Fibonacci equation correctly, but obviously I am doing something incorrectly.
Could anyone help me through this please?
(True, I could easily google some code for this as I am sure it is out there, but I want to actually learn how this is done and what I am doing wrong for future reference. Better to advance as a programmer than to get the grade from copied code and move on)
I think you are a little confused here with what the Fibonacci sequence is. The formula is F(n) = F(n-1) + F(n-2). Recursion should always end at a base case which for Fibonacci is F(0) = 0 and F(1) = 1. Your method only needs one variable which is n.
Think about it this way:
public static int fibonacci(int n) {
//Insert your base cases here to terminate early
//Then process the recursive formula
return fibonacci(n - 1) + fibonacci(n - 2);
}
I think I understand what you are trying to do. You want 10 fibonacci numbers from start. Perhaps something like this will work:
public static int[] fibonacci(int start, int times)
{
return fibonacci(start, times, 0, 1, new int[times]);
}
private static int[] fibonacci(int start, int times, int a, int b, int[] answer)
{
if( start > 0 )
return fibonacci(start-1, times, b, a+b, answer);
if( times > 0 )
{
answer[answer.length - times] = a;
return fibonacci(start, times-1, b, a+b, answer);
}
return answer;
}
public static void main(String[] args) {
int[] a = fibonacci(5, 10);
for(int i=0; i<a.length; i++)
{
System.out.println(a[i]);
}
}
I have a piece of code and I could not figure out why it is giving me Exception in thread "main" java.lang.StackOverflowError.
This is the question:
Given a positive integer n, prints out the sum of the lengths of the Syracuse
sequence starting in the range of 1 to n inclusive. So, for example, the call:
lengths(3)
will return the the combined length of the sequences:
1
2 1
3 10 5 16 8 4 2 1
which is the value: 11. lengths must throw an IllegalArgumentException if
its input value is less than one.
My Code:
import java.util.HashMap;
public class Test {
HashMap<Integer,Integer> syraSumHashTable = new HashMap<Integer,Integer>();
public Test(){
}
public int lengths(int n)throws IllegalArgumentException{
int sum =0;
if(n < 1){
throw new IllegalArgumentException("Error!! Invalid Input!");
}
else{
for(int i =1; i<=n;i++){
if(syraSumHashTable.get(i)==null)
{
syraSumHashTable.put(i, printSyra(i,1));
sum += (Integer)syraSumHashTable.get(i);
}
else{
sum += (Integer)syraSumHashTable.get(i);
}
}
return sum;
}
}
private int printSyra(int num, int count){
int n = num;
if(n == 1){
return count;
}
else{
if(n%2==0){
return printSyra(n/2, ++count);
}
else{
return printSyra((n*3)+1, ++count) ;
}
}
}
}
Driver code:
public static void main(String[] args) {
// TODO Auto-generated method stub
Test s1 = new Test();
System.out.println(s1.lengths(90090249));
//System.out.println(s1.lengths(5));
}
.
I know the problem lies with the recursion. The error does not occur if the input is a small value, example: 5. But when the number is huge, like 90090249, I got the Exception in thread "main" java.lang.StackOverflowError. Thanks all for your help. :)
I almost forgot the error msg:
Exception in thread "main" java.lang.StackOverflowError
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:65)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:65)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)
Your algorithm is fine. However int is too small for your computations, it fails for this input:
printSyra(113383, 1);
At some point integer overflows to negative value and your implementation goes crazy, recursing infinitely. Change int num to long num and you'll be fine - for some time. Later you'll need BigInteger.
Note that according to Wikipedia on Collatz conjecture (bold mine):
The longest progression for any initial starting number less than 100 million is 63,728,127, which has 949 steps. For starting numbers less than 1 billion it is 670,617,279, with 986 steps, and for numbers less than 10 billion it is 9,780,657,630, with 1132 steps.
The total number of steps is equivalent to maximum nesting level (stack depth) you can expect. So even for relatively big numbers StackOverflowError should not occur. Have a look at this implementation using BigInteger:
private static int printSyra(BigInteger num, int count) {
if (num.equals(BigInteger.ONE)) {
return count;
}
if (num.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
return printSyra(num.divide(BigInteger.valueOf(2)), count + 1);
} else {
return printSyra(num.multiply(BigInteger.valueOf(3)).add(BigInteger.ONE), count + 1);
}
}
It works even for very big values:
printSyra(new BigInteger("9780657630"), 0) //1132
printSyra(new BigInteger("104899295810901231"), 0) //2254
This is an inherent problem with recursive algorithms. Make the number of recursions large enough and you can't really avoid a stack overflow, unless the language can guarantee tail-call optimization (Java and most C-like languages don't). The only way to truly fix it is to "unroll" the recursion, rewriting the algorithm iteratively or with a helper function to simulate the state-passing of the recursive call without actually nesting calls.
One solution is to allow the JVM to take more space for stack recursion, using the java -Xss parameter. Its default is less than a megabyte, IIRC, which could limit to a couple of hundred recursions max.
A better solution is to rewrite the exercise without recursion:
private int printSyra(int num){
int count = 1;
int n = num;
while(n != 1){
if(n%2==0){
n = n/2;
++count;
}
else{
n=(n*3)+1;
++count;
}
}
return count;
}