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]);
}
}
Related
I am new to Java and am I trying to implement a recursive method for finding "n choose k".
However, I've run into a problem.
public class App {
public static void main(String[] args) throws Exception {
int n = 3;
int k = 2;
int result = combRecursion(n, k);
System.out.println(result);
}
private static int combRecursion(int n, int k) {
if (k == 0) {
return 1;
} else {
return (combRecursion(n - 1, k - 1) + combRecursion(n - 1, k));
}
}
Output:
many repetitions of this line:
at App.combRecursion(App.java:14)
It's possible to pick k items from the set of n items only if n is greater or equal to k.
You need to cut off fruitless branches of recursion spawn by the call combRecursion(n - 1, k) which doesn't reduce the number of item in the sample.
When you need to create a recursive method, it should always contain two parts:
Base case - that represents a set of edge-cases, trivial scenarios for which the result is known in advance. If the recursive method hits the base case (parameters passed to the method match one of the conditions of the base case), recursion terminates. In for this task, the base case will represent a situation when the source list was discovered completely and position is equal to its size (invalid index).
Recursive case - a part of a solution where recursive calls are made and where the main logic resides.
Your recursive case is correct: it spawns two recursive branches of execution (one will "pick" the current item, the second will "reject" it).
But in the base case, you've missed the scenario mentioned above, we need to address these situations:
n isn't large enough (k > n), so that is not possible to fetch k item. And the return value will be 0 (or instead of returning a value, you might throw an exception).
k == 0 result should be 1 (it's always possible to take 0 items, and there's only one way to do it - don't pick anything).
When k == n - there's only one way to construct a combination, as #akuzminykh has pointed out. And the return value will be 1
Note that because your goal is to get familiar with the recursion (I'm pretty sure that you're doing it as an exercise) there's no need to mimic the mathematical formula in your solution, use pure logic.
Here is how you can implement it:
private static int combRecursion(int n, int k) {
if (k > n) return 0; // base case - impossible to construct a combination
if (n == k || k == 0) return 1; // base case - a combination was found
// recursive case
return combRecursion(n - 1, k - 1) + combRecursion(n - 1, k);
}
main() - demo
public static void main(String[] args) {
System.out.println(combRecursion(3, 2));
System.out.println(combRecursion(5, 2));
}
Output
3 // pick 2 item from the set of 3 items
10 // pick 2 item from the set of 5 items
Your base case ought to include both n == k || k == 0 for "n choose k" to be implemented correctly. That way, both calls will eventually terminate (even though your current implementation is rather inefficient as it has exponential runtime). A better implementation would use the formula n!/k!/(n-k)! or the multiplicative formula to run in linear time:
int factorial(int n) {
int res = 1;
for (; n > 1; n--) {
res *= n;
}
return res
}
int choose(int n, int k) {
return factorial(n)/factorial(k)/factorial(n-k);
}
further optimizing this is left as an exercise to the reader (hint: a single for loop suffices).
(This may seem like this was already answered, but I am looking something more specific.) For schoolwork I need to write a method that calculates the different ways a rectangle can be tiled by a domino tile of 2*1. From what I can see, it would be the fibonacci numbers of the area. I wrote code that compiled in the compiler, but not sure it really makes sense and am clueless where to go from here. How would I be able to implement this better?
public static int domino(int n, int m) // the method signature is what I must use according the hw instructions
{
int area = n*m; // calculating the area of the passed in rectangle
int dominoes = area/2; // calculating how many dominos will be needed to cover the area
if (dominoes<=2) { // because fib 1 equals 1 and fib 2 equals 1
return 1;
} //also the stopping point
else {return domino(dominoes-1, 0) + domino(dominoes-2, 0);}
}
I do not need to worry about efficiency for this homework.
You are not correctly computing the Fibonacci numbers using your recursive calls. You are executing:
else {return domino(dominoes-1, 0) + domino(dominoes-2, 0);}
So essentially, in the first recursive call n == (dominoes - 1) and m == 0. This means that calculating the area always results in 0, as multiplying anything by 0 equals 0.
My advice would be to use an extra Fibonacci function like so:
public static int domino(int n, int m) {
// return the fibonacci number of the number of dominoes in the given rectangle
return fib((n * m) / 2);
}
public static int fib(int n) {
if(n <= 2)
// seed values of the fibonacci sequence
return 1;
else
return fib(n - 1) + fib(n - 2);
}
I'm trying to implement a code that returns the sum of all prime numbers under 2 million. I have an isPrime(int x) method that returns true if the the number is prime. Here it is:
public static boolean isPrime(int x) {
for (int i = 2; i < x; i++) {
if (x % i == 0) {
return false;
}
}
return true;
}
And the other method, which I'm trying to implement recursively, only works until a certain number, over that number and I get a stack overflow error. The highest I got the code to work was for 10,000.
Here it is:
public static int sumOfPrimes(int a) {
if (a < 2000000) { //this is the limit
if (isPrime(a)) {
return a + sumOfPrimes(a + 1);
} else {
return sumOfPrimes(a + 1);
}
}
return -1;
}
So why do I get a stack overflow error when the number gets bigger and how can I deal with this?
Also, how do you normally deal with writing code for such big numbers? IE: normal number operations like this but for larger numbers? I wrote this recursively because I thought it would be more efficient but it still wont work.
Your isPrime function is inefficient, it doesn't have to go to x, it's enough to go to the square root of x.
But that is not the reason why your solution doesn't work. You cannot have a recursion depth of 1 million.
I would solve this problem iteratively, using the sieve of eratosthenes and for loop over the resulting boolean array.
In general if you would still like to use recursion, you can use tail recursion.
In recursion each function call will push some data to the stack, which is limited, thus generating a stackoverflow error. In tail recursion you won't be pushing anything to the stack, thus not throwing the exception.
Basically all you need is sending the data of the previous computation as parameter instead of having it on the stack.
So:
function(int x) {
// end condition
return function(x - 1) + x;
}
with tail recursion would be
function (int max, int curr, int prev, int sum) {
if (curr > max)
return sum;
return function (max, curr + 1, curr, sum + curr)
}
Keep in mind this is just pseudo code not real java code, but is close enough to the java code.
For more info check
What is tail recursion?
Use Sieve of Eratosthenes:-
Following is the algorithm to find all the prime numbers less than or equal to a given integer n by Eratosthenes’ method:
1) Create a list of consecutive integers from 2 to n: (2, 3, 4, …, n).
2) Initially, let p equal 2, the first prime number.
3) Starting from p, count up in increments of p and mark each of these numbers greater than p itself in the list. These numbers will be 2p, 3p, 4p, etc.; note that some of them may have already been marked.
4) Find the first number greater than p in the list that is not marked. If there was no such number, stop. Otherwise, let p now equal this number (which is the next prime), and repeat from step 3.
public static void main(String[] args) {
int n = 30;
System.out.printf("Following are the prime numbers below %d\n", n);
SieveOfEratosthenes(n);
}
static void markMultiples(boolean arr[], int a, int n)
{
int i = 2, num;
while ( (num = i*a) <= n )
{
arr[ num-1 ] = true; // minus 1 because index starts from 0.
++i;
}
}
// A function to print all prime numbers smaller than n
static void SieveOfEratosthenes(int n)
{
// There are no prime numbers smaller than 2
if (n >= 2)
{
// Create an array of size n and initialize all elements as 0
boolean[] arr=new boolean[n];
for(int index=0;index<arr.length-1;index++){
arr[index]=false;
}
for (int i=1; i<n; ++i)
{
if ( arr[i] == false )
{
//(i+1) is prime, print it and mark its multiples
System.out.printf("%d ", i+1);
markMultiples(arr, i+1, n);
}
}
}
}
Output:-
Following are the prime numbers below 30
2 3 5 7 11 13 17 19 23 29
I have written multiple attempts to this problem, but I think this is the closest I could get. This solution makes the method recurse infinitely, because I don't have a base case, and I can't figure it out. The counter++ line is unreachable, and I can't get this to work, and I am very tired. This would be very easy with a loop, but recursion is kind of a new concept to me, and I would be thankful if someone helped me solve this.
public static double pi(int a, double b){
int counter=0;
if (counter %2==0){
return a-(a/(pi(a,b+2)));
counter++;
} else {
return a+(a/(pi(a,b+2)));
counter++;
}
You could pass in another int, say limit, and add this code:
if (b > limit) {
return a;
}
Or you could pass in some tolerance value:
if (pi(a,b+2) < tolerance) {
return a;
}
Whenever you're working with recursion it's good to establish an exit strategy up front.
Here is an implementation that works. Do not use it:
public static double term(double acc, int n, int r) {
if (r-- > 0) {
double sgn = (n % 4 == 1) ? +1.0 : -1.0;
acc += sgn * 4.0 / n;
n += 2;
return term(acc, n, r);
} else {
return acc;
}
}
public static double pi() {
return term(0.0, 1, 1000);
}
The reason not to use it is that this particular infinite series is a particularly poor way of calculating π because it converges very slowly. In the example above event after 1000 iterations are performed it's still only correct to 3 decimal places because the final calculated term is 4 / 1000.
Going much beyond 1000 iterations results in a stack overflow error with little improvement in the accuracy even though the term function is (I think) potentially tail recursive.
I have some code that needs to run with some rather large numbers, and it involves incrementing into a recursive method and is therefor very slow to the point where I can't even get to my desired answer. Could someone help me optimize it? I am a beginner though, so I can't do anything very complex/difficult.
public class Euler012{
public static void main(String[]args){
int divisors=0;
for(long x=1;divisors<=501;x++){
divisors=1;
long i=triangle(x);
for(int n=1;n<=i/2;n++){
if(i%n==0){
divisors++;
}
}
//System.out.println(divisors+"\n"+ i);
System.out.println(i+": " + divisors);
}
}
public static long triangle(long x){
long n=0;
while(x>=0){
n+=x;
x--;
triangle(x);
}
return n;
}
}
First: i don't think its an optimization problem, because its a small task, but as mentioned in the comments you do many unnecessary things.
Ok, now lets see where you can optimize things:
recursion
recursion has usually a bad performance, especially if you don't save values this would be possible in your example.
e.g.: recursive triangle-number function with saving values
private static ArrayList<Integer> trianglenumbers = new ArrayList<>();
public static int triangleNumber(int n){
if(trianglenumbers.size() <= n){
if(n == 1)
trianglenumbers.add(1);
else
trianglenumbers.add(triangleNumber(n-1) + n);
}
return trianglenumbers.get(n-1);
}
but as mentioned by #RichardKennethNiescior you can simply use the formula:
(n² + n)/2
but here we can do optimization too!
you shouldnt do /2 but rather *0.5 or even >>1(shift right)
but most compilers will do that for you, so no need to make your code unreadable
your main method
public static void main(String[]args){
int divisors = 0; //skip the = 0
for(long x=1;divisors<=501;++x){ // ++x instead of x++
divisors=0;
long i=(x*x + x) >> 1; // see above, use the one you like more
/*how many divisors*/
if(i == 1) divisors = 1;
else{ /*1 is the only number with just one natural divisor*/
divisors = 2; // the 1 and itself
for(int n = 2; n*n <= i; ++n){
if(n*n == i) ++divisors;
else if(i%n == 0) divisors += 2;
}
}
System.out.println(i+": " + divisors);
}
}
the ++x instead of x++ thing is explained here
the how many divisors part:
every number except 1 has at least 2 divisors (primes, the number itself and one)
to check how many divisors a number has, we just need to go to the root of the number
(eg. 36 -> its squareroot is 6)
36 has 9 divisors (4 pares) {1 and 36, 2 and 18, 3 and 12, 4 and 8, 6 (and 6)}
1 and 36 are skiped (for(**int n = 2**)) but counted in divisors = 2
and the pares 2, 3 and 4 increase the number of divisors by 2
and if its a square number (n*n == i) then we add up 1
You dont have to generate a new triangle number from scratch each time, if you save the value to a variable, and then add x to it on the next iteration, you dont really need to have the triangle method at all.