How to solve this summation in a recursive way - java

Today, my teacher asked us to implement the next expression using recursion in Java (where n is a value asked to the user):
It is possible? I can't find a proper solution for this problem, but I think I will need two recursive methods.
UPDATE
So far I have done this:
public static double sumatorio(int n){
if(n==1)
return 1;
else{
return (1 + ((n-1) * segundoSumatorio(n))) + sumatorio(n-1);
}
}
public static double segundoSumatorio(int n){
if(n==1)
return 1;
else
return 1/(double)n + segundoSumatorio(n-1);
}
It looks like it's correct, but when n=3 or greater, the result is not exact. Someone knows why?
Maybe there is an error related with losing precision.
I really appreciate any help you can provide.

Hints:
Yes. One possible solution does involve two recursive methods.
(And it is a good solution ... )
Factor the problem (and the solution) into two parts; e.g. the complete "sigma" and the embedded "sigma".

Here is your code fixed. Note how the 2nd sumatorio needs 2 parameters,
and how I don't change the second parameter while calling it recursively.
This is what your formula says and not what you implemented.
This is not a precision error, you could have figured that out
because this error sounds too big for a precision error for such
small values of n.
public class Test {
public static void main(String a[]) throws Exception {
System.out.println(sumatorio(1));
System.out.println(sumatorio(2));
System.out.println(sumatorio(3));
System.out.println(sumatorio(4));
}
public static double sumatorio(int n){
return sumatorio(n ,n);
}
public static double sumatorio(int n, int m){
if(n==1)
return 1;
else{
return (1 + ((n-1) * segundoSumatorio(m))) + sumatorio(n-1, m);
}
}
public static double segundoSumatorio(int n){
if(n==1)
return 1;
else
return 1/(double)n + segundoSumatorio(n-1);
}
}

If this task is too hard for you, try splitting it in smaller chunks. The question asks for a summation, implemented by recurse. I am confident you can do summation by implementing a loop. Something like:
int sum = 0;
for(int i = 1; i < n; i++){
sum = sum+i;
}
This will sum all numbers from 1 to (n-1).
You can convert the loop into recursion by writing a simple adding method:
int sum = 0;
int doSum(int n){
if(n <= 1){
return 1;
}
else{
return n + doSum(n - 1);
}
}
sum = doSum(n);
From here on I think you should be able to catch up.
Splitting the problem into smaller subproblems is a technique used by ALL programmers. Start small and easy, adding complexity as you go.

Related

Given a fibonacci method/function, implement it and make it efficient

Hey guys so in my interview question I was given something like this below. By the way this is my code to solve fib. I want to improve this my code to eliminate repetition of fibonacci sequence that might end up being repeated at the process. For example if fib(1) and fib(1) are repeated twice, how to do I avoid this from happening so the program can advance to unique sequence being processed.
I really want to know how to improve this code. My solution is below but when I debug it, I feel like I get lost understanding what is really happening.
Thanks.
public class Fib {
public static void main(String[] args) {
System.out.print(fibonacci(14));
}
private static int fibonacci(int n) {
int fibArray[] = new int[n];
if (n <= 0) {
return 1;
} else if (n == 1) {
return 1;
} else {
fibArray[0] = fibonacci(n - 1);
fibArray[1] = fibonacci(n - 2);
if (fibArray[0] == fibonacci(n - 1)) {
return fibonacci(n - 1) + fibonacci(n - 2);
} else if (fibArray[1] != fibonacci(n - 2)) {
return fibonacci(n - 1) + fibonacci(n - 2);
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
}
}
To solve the nth Fibonacci number, basic recursion like your answer is not the best way.
There is a complicated matrix method to solve Fibonacci that uses O(log(n)) runtime and O(log(n)) memory.
If you want performance and simplicity in your Fibonacci solution, this is a neat formula (though this is memorization and defeats the problem solving part of the interview):
Here is a Java method implementation:
public Long fibonacci(int n)
{
double sqrt5 = Math.sqrt(5);
int tmp1 = (int)(1+sqrt5)/2;
int tmp2 = (int)(1-sqrt5)/2;
return (long) Math.ceil((Math.pow(tmp1, n) - Math.pow(tmp2, n))/sqrt5);
}
This method looks O(1) but it's not quite as the Math.pow() is O(log(n)). It uses O(1) memory.
As #PavelS mentioned. Should be something similar to this where n is your parameter:
int a = 0;
int b = 1;
// In N steps compute Fibonacci sequence iteratively.
for (int i = 0; i < n; i++)
{
int temp = a;
a = b;
b = temp + b;
}
return a;
You need to store the value once computed. If value is present, dont compute again, just use it, else calculate and store:
public class Fib {
static int fibo[]=new int[100];
public static void main(String[] args) {
Arrays.fill(fibo, 0);
System.out.print(fibonacci(24));
}
private static int fibonacci(int n) {
if (n <= 0)
fibo[n]=0;
else if (n == 1)
fibo[n]= 1;
else if(fibo[n]==0)
fibo[n]=fibonacci(n-1)+fibonacci(n-2);
return fibo[n];
}
}
Lets generalize this a little.
There are many techniques that can be used to optimize a recursive function. Here are some of them:
Memoization: you may be able to reduce the cost of repeated calls to an (expensive) function f(n) with the same argument. This can be done by creating a map n -> f(n) and doing a map lookup before making the expensive call.
Converting recursion into iteration. A compiler for a functional programming language will typically do this automatically for simple cases (tail calls). The Java compiler won't (for technical reasons which are off track) ... but you can do the same optimization at the source code level.
Converting call-stack recursion into iteration with a stack-like data structure. This is something you might do in Java to avoid StackOverflowError exceptions in deeply recursive problems that are no amenable to other optimizations.
The solution might be to solve a recurrence relation rather than trying to compute it.
Obviously, not all techniques will work for any given problem.
The other answers give examples of most of approaches.
Approach #1 - #Dip
Approach #2 - #FirstStep
Approach #4 - #PhotometricStereo

Strange behavior in recursive algorithm,

I was writing a recursive algorithm to calculate Fibonacci numbers in Java as part of a programming 101 course. This is the code:
public class Fib {
public static void main(String[] args) {
Fib fib = new Fib();
}
public Fib() {
int end = 9;
long[] nums = new long[2];
printFib(0, end, nums);
}
private void printFib(int i, int end, long[] nums) {
while(i < end) {
if(i == 0 || i == 1) {
nums[i] = 1;
System.out.println("1");
} else {
long fib;
fib = 0;
fib += (nums[0] + nums[1]);
nums[0] = nums[1];
nums[1] = fib;
System.out.println(fib);
}
i++;
printFib(i, end, nums);
}
}
}
As I was stepping through the program it was working as intended until i became equal to end, the variable telling the printFib method how many Fibonacci numbers it should print out. When ì was equal to end while(i < 1) returns false as expected and the program go to the last }, now you'd(me)
expect the program to return the constructor from which I initially called the function and the program should exit, this not the case. The program goes back to the while statement and somehow evaluates to false again. Then it does the same thing again except the second time it decreases i by 1(what?!) and then proceeds to the else clause when it reaches the if statement. It then does the same thing over and over alternating the amount it subtracts from i between 1 and 2. I've asked my teacher about this and he was unable to explain it.
The program works fully like I intended if I replace the while with an if so maybe there is something about while that I don't know.
Edit
So I realize now that each time the method is called i has a different value which is stored and when the method exits and i = end the program goes back to the previous calls where i had a different value.
You implemented an iterative algorithm to calculate Fibonacci series. That's what the while loop does. There is no point in making the recursive call - printFib(i, end, nums) - at the end.
If you intended a recursive implementation, the entire while loop is not needed.
This code doesn't look right to me.
I would recommend that you not print from your method. Return a value to the main and let it print.
Your recursive method should not have a while loop in it. That's iteration - exactly what you're trying to avoid here.
Your method should have a stopping condition and a call to itself. That's not what you're doing.
Think about it like this:
/**
* Recursive Fibonnaci
* User: mduffy
* Date: 2/11/2015
* Time: 8:50 AM
* #link http://stackoverflow.com/questions/28455798/strange-behavior-in-recursive-algorithm/28455863#28455863
*/
public class Math {
private static Map<Integer, Integer> memo = new ConcurrentHashMap<Integer, Integer>();
public static void main(String [] args) {
for (String arg : args) {
int n = Integer.valueOf(arg);
System.out.println(String.format("n: %d fib(n): %d", n, fibonnaci(n)));
}
}
public static int fibonnaci(int n) {
if (n < 0) throw new IllegalArgumentException("index cannot be negative");
int value = 0;
if (memo.containsKey(n)) {
value = memo.get(n);
} else {
if (n <= 1) {
value = n;
} else {
value = fibonnaci(n-1)+fibonnaci(n-2);
}
memo.put(n, value);
}
return value;
}
}
Basicly this is happening because i would guess that you are thinking of i as an reference which will influence the basic callings of the Fibunacci method calling the sub Fibunacci method. This will finally lead way to many calls of the fibunacci method.
in my eyes the loop doesn´t make sense in your recursive way of solving it.

Sieve of Eratosthenes without arrays?

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.

How to Check Array for 3 Numbers that Add to a Specific value in JAVA?

Alright guys, I've been stuck on this problem for a while now and have not been able to get past it. This is for Java. I'd appreciate any help at this point. Here are the details: Please note, we must do this in O(n) running time. We are given an array of numbers and must go through it to determine if there are any 3 numbers that sum to a specific number. HOWEVER, we are allowed to reuse any number in the array up to 3 times because we need a total of 3 numbers. We also have to output which 3 numbers gave the sum. Returning true or false.
Below is what I've got:
Do you guys have any suggestions?
You can make a for loop inside of a for loop inside of a for loop. This is for school, so I wont give you the code, but I'll give you the pseudo.
Edit: missed the O(n) part, sorry. This way should work.
public static void main(String[] args)
{
int[] test = {1,8,2,3,11,4};
System.out.println(threeSumTo(test, 6));
}
//check if 3 numbs in an array add up to int x
public static boolean threeSumTo(int[] array, int x)
{
//loop through the array
for (int i = 0; i < array.length; i++) {
boolean result = twoSumTo(array, x - array[i], i);
if (result) {
return result;
}
}
return false;
}
private static boolean twoSumTo(int[] array, int x, int low) {
int high = array.length - 1;
while (low < high) {
if (array[low] + array[high] == x) {
return true;
}
if (array[low] + array[high] > x) {
high--;
} else {
low++;
}
}
return false;
}
}
This seems to be a variation of the 3SUM problem and should obey the same restrictions.
Computing the 3SUM problem in less than O(n^2) is still a unsvoled problem.
Did your teacher ask a trick question or is that some kind of competition?
This is called a 3 sum problem and solving this problem in O(N) is impossible till now. The best you can do is O(N^2).
Check this article out.

factorial method doesn't work well!

Hi
this is a factorial method but it prints 0 in the console please help me thanks
public class Demo {
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.factorial(500));
}
public int factorial(int n) {
int fact = 1;
for (int i = 2; i <= n; i++) {
fact= fact*i;
}
return fact;
}
EDITED:will return Infinity!
public class Demo {
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.factorial(500));
}
public double factorial(long n) {
double fact = 1;
for (int i = 2; i <= n; i++) {
fact= fact*i;
}
return fact;
}
}
Since 500! equals 1220136825991110068701238785423046926253574342803192842192413588385845373153881997605496447502203281863013616477148203584163378722078177200480785205159329285477907571939330603772960859086270429174547882424912726344305670173270769461062802310452644218878789465754777149863494367781037644274033827365397471386477878495438489595537537990423241061271326984327745715546309977202781014561081188373709531016356324432987029563896628911658974769572087926928871281780070265174507768410719624390394322536422605234945850129918571501248706961568141625359056693423813008856249246891564126775654481886506593847951775360894005745238940335798476363944905313062323749066445048824665075946735862074637925184200459369692981022263971952597190945217823331756934581508552332820762820023402626907898342451712006207714640979456116127629145951237229913340169552363850942885592018727433795173014586357570828355780158735432768888680120399882384702151467605445407663535984174430480128938313896881639487469658817504506926365338175055478128640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 you can't fit it into an int (which ranges up to 2147483647).
Using an int you can only store up to 12!.
Using a long you'll get up to 20!
Using a double you'll get up to 170!.
By convention 0! equals 1;
Here is a solution using BigInteger:
public static BigInteger factorial(int i) {
if (i == 0) {
return BigInteger.ONE;
}
BigInteger n = BigInteger.valueOf(i);
while (--i > 0) {
n = n.multiply(BigInteger.valueOf(i));
}
return n;
}
There's no way you can fit 500! on a 32-bit int.
For calculations involving large numbers, consider using a double or a BigInteger, depending on whether you want an approximate or an exact answer.
(Actually, for 500!, even a double would not be enough: Double.MAX_VALUE is 1.7976931348623157E+308, which will "only" let you go up to 170!)
There are two things you should be looking into if you need to calculate the factorial function:
1) Memoization. This will dramatically speed up your calculations, since the factorial function has a recursive definition. What you do is cache previous calculations, so when you ask for k!, you can get it in one step by calculating k*((k-1)!) if you have (k-1)! cached.
2) Stirling's approximation. If you need to calculate large factorials, you can approximate them very rapidly this way, and with guaranteed bounds on the error, so you can tell whether the approximation will be acceptably close for your application.
If you do neither of these, you will find that there is some relatively small k for which you simply can't calculate k! in a reasonable amount of time.
Grodriguez is right - this is almost certainly caused by integer overflow.
If you test your method with more modest inputs it appears to return the right output:
public static void main(String[] args) {
Demo obj = new Demo();
for (int i = 0; i < 10; i++)
System.out.println(i + "! = " + obj.factorial(i));
}
500! is massive; when testing your function, starting with smaller inputs would be prudent.
500! is way too big to fit a long, or double.
You would have to use other techniques to get this.
But first, what kind of program needs 500!?
There are some very nice optimization for the implementation of factorizations: see for instance luschny.de for a nice implementation of them in Java. Some require more mathematical insight then others... Have fun with the library :-)

Categories