Basic Java Recursion Method - java

I am having a lot of trouble with this basic recursion problem in java; any pointers would be great.
"Write a static recursive method to print out the nth term of the
geometric sequence: 2, 6, 18, 54."
From what I can gather, somewhere in the code I should be recursively multiplying something by 3, but I'm struggling to figure out how to do this. I know I need a termination statement, but when does that occur? Do I need a helper method?

A Recursive Function is a function whose implementation references itself. Below is some funny example:
public class Inception {
public void dream() {
boolean enoughDreaming = false;
//Some code logic below to check if it's high time to stop dreaming recursively
...
...
if(!enoughDreaming) {
dream(); //Dream inside a Dream
}
}
}
And the solution for your problem:
public class GeometricSequence {
public static void main(String[] args) {
//Below method parameters - 5 = n, 1 = count (counter), res = result (Nth number in the GP.
System.out.println(findNthNumber(5, 1, 2));
}
public static int findNthNumber(int n, int count, int res) {
return ((count == n)) ? res : findNthNumber(n, count+1, res *3);
}
}
EDIT:
The above class uses "int", which is good only for small numbers (because of Integer Overflow problem). The below class is better for all types/numbers:
public class GeometricSequence {
public static void main(String[] args) {
//Below method parameters - 5 = n, 1 = count (counter), res = result (Nth number in the GP.
System.out.println(findNthNumber(2000, 1, new BigInteger("2")));
}
public static BigInteger findNthNumber(int n, int count, BigInteger res) {
return ((count == n)) ? res : findNthNumber(n, count+1, res.multiply(new BigInteger("3")));
}
}

This is the simplest example of recursion.
You need a method declaration.
You need to check if the end has been reached.
Otherwise you need to call the method again with an operation which makes the difference between one term and the next.

Yes, you need a termination condition - basically when you've taken as many steps as you need. So consider how you want to transition from one call to another:
How are you going to propagate the results so far?
What extra state do you need to keep track of how many more steps you need to take?
What are you going to return from the method?

Here's a C# example (I know your doing Java but it's pretty similar)
public static void Recursive(int counter, int iterations, int value, int multiplier)
{
if (counter < iterations)
{
Console.WriteLine(value);
counter++;
Recursive(counter, iterations, (value * multiplier), multiplier);
}
}
So when you run the function you enter the parameters
"counter" will always be 0 when you first call it
"iterations" is the value of n
"value" is your starting value, in your case 2
"multiplier" is how much you want to multiply by each iteration, in your case 3
Every time it runs it will check to see if counter is less than iterations. If it is more, the value is printed, the counter is incremented, the value is multiplied by the multiplier and you add the same parameters back in to the function.

A recursive solution: Seq(1) is the first element of the sequence .... Seq(n-th)
public static void main(String args[]) throws Exception {
int x = Seq(3); //x-> 18
}
public static int Seq(int n){
return SeqRec(n);
}
private static int SeqRec(int n){
if(n == 1)
return 2;
else return SeqRec(n - 1) * 3;
}
Non-Recursive solution:
public static int Non_RecSeq(int n){
int res = 2;
for(int i = 1; i < n; i ++)
res *= 3;
return res;
}
public static void main(String args[]) throws Exception {
int x = Non_RecSeq(3); //x-> 18
}

Related

understanding recursion for dot product in java

Could anyone give me some clue about how could I Transform this code to recursion:
public class arrayExample {
public static void main (String[] args) {
int[] a = {2,2,2,2};
int[] b = {2,2,2,2};
int n = a.length;
int sum = 0;
for (int i = 0; i < n; i++) {
sum += a[i] * b[i];
}
System.out.println(sum);
}
}
So to do this do product with recursion.
You asked for a hint, so I'm not giving you the complete solution. When you want to process a list (or an array) recursively, the concept is nearly always:
public int recursiveFunction(List l, int carry) {
if (l.isEmpty()) {
return carry;
}
return recursiveFunction(l.subList(1, l.size()), operation(carry, l.get(0));
}
Where operation is whatever you want to do with your list. carry is used to provide an initial value (in the first call) and save the interim results.
You just have to change the code so it uses two arrays instead of one list and choose the correct operation.
Ok so hoping you have tried it before this is one possible way to code it.
public class ArrayExample {
public static void main (String[] args) {
int[] a = {2,2,2,2};
int[] b = {2,2,2,2};
int n = a.length;
int result = recurseSum(a, b, n-1);
System.out.println(result);
}
public static int recurseSum(int[] a, int[] b, int n){
if(n == 0)
return a[0]*b[0];
else{
return (a[n] * b[n]) + recurseSum(a,b,n-1);
}
}
}
This code is basically doing the same thing in the iteration.
The recursive call happens 4 times. When n hits 0, a[0]*b[0] is returned to the higher call. so basically from right to left it happens as follows:
a[3]*b[3] + a[2]*b[2] + a[1]*b[1] + a[0]*b[0]
One simple way to make a loop into a recursion is to answer these two questions:
What happens when the loop executes zero times?
If the loop has already executed n-1 times, how do I compute the result after the n-th iteration?
The answer to the first case produces your base case; the answer to the second question explains how to do the recursive invocation.
In your case, the answers are as follows:
When the loop executes zero times, the sum is zero.
When the loop executed n-1 times, add a[n] * b[n] to the previous result.
This can be translated into a recursive implementation
static int dotProduct(int[] a, int[] b, int n) {
... // your implementation here
}

How does Linear Recursion work?

I have written a java program to add elements in an array using Linear Recursion. The output obtained is not as expected. Can anyone point what is wrong with this program?
public class TestSum {
public int count = 0;
public int sum(int[] a){
count++;
if(a.length == count){
return a[count -1];
}
return sum(a) + a[count -1] ;
}
public static void main(String[] args) {
int[] a = {1,2,3};
int val = new TestSum().sum(a);
System.out.println(val);
}
}
I am expecting the output as 6 but obtained is 9. What is wrong?
Strangely if I change the order of addition i.e. return a[count -1] + sum(a); then it gives output as 6.
Generally, recursive programs that are not re-entrant (i.e. relying on external state) are suspicious. In your particular case count will change between invocations of sum, making the behavior hard to trace, and ultimately resulting in the error that you observe.
You should pass the index along with the array to make it work:
// The actual implementation passes the starting index
private static int sum(int[] a, int start){
if(a.length == start){
return 0;
}
return sum(a, start+1) + a[start];
}
// Make sure the method can be called with an array argument alone
public static int sum(int[] a) {
return sum(a, 0);
}
Unlike an implementation that increments the count external to the method, this implementation can be called concurrently on multiple threads without breaking.

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.

recursion resulting in extra unwanted data

I'm writing a module to handle dice rolling. Given x die of y sides, I'm trying to come up with a list of all potential roll combinations.
This code assumes 3 die, each with 3 sides labeled 1, 2, and 3. (I realize I'm using "magic numbers" but this is just an attempt to simplify and get the base code working.)
int[] set = { 1, 1, 1 };
list = diceroll.recurse(0,0, list, set);
...
public ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
if(index < 3){
// System.out.print("\n(looping on "+index+")\n");
for(int k=1;k<=3;k++){
// System.out.print("setting i"+index+" to "+k+" ");
set[index] = k;
dump(set);
recurse(index+1, i, list, set);
}
}
return list;
}
(dump() is a simple method to just display the contents of list[]. The variable i is not used at the moment.)
What I'm attempting to do is increment a list[index] by one, stepping through the entire length of the list and incrementing as I go.
This is my "best attempt" code. Here is the output:
Bold output is what I'm looking for. I can't figure out how to get rid of the rest. (This is assuming three dice, each with 3 sides. Using recursion so I can scale it up to any x dice with y sides.)
[1][1][1] [1][1][1]
[1][1][1] [1][1][2] [1][1][3] [1][2][3]
[1][2][1] [1][2][2] [1][2][3] [1][3][3]
[1][3][1] [1][3][2] [1][3][3] [2][3][3] [2][1][3]
[2][1][1] [2][1][2] [2][1][3] [2][2][3]
[2][2][1] [2][2][2] [2][2][3] [2][3][3]
[2][3][1] [2][3][2] [2][3][3] [3][3][3] [3][1][3]
[3][1][1] [3][1][2] [3][1][3] [3][2][3]
[3][2][1] [3][2][2] [3][2][3] [3][3][3]
[3][3][1] [3][3][2] [3][3][3]
I apologize for the formatting, best I could come up with.
Any help would be greatly appreciated. (This method was actually stemmed to use the data for something quite trivial, but has turned into a personal challenge. :)
edit: If there is another approach to solving this problem I'd be all ears, but I'd also like to solve my current problem and successfully use recursion for something useful.
edit2:
Running code including the "easy fix." Beware unused variables and weird hacks, I haven't cleaned it up yet.
package code.testing;
import java.util.ArrayList;
public class CodeTesting {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
int[] set = { 1, 1, 1 };
list = recurse(0,0, list, set);
}
public static ArrayList<Integer> recurse(int index, int i, ArrayList<Integer> list, int[] set){
if(index < 3){
// System.out.print("\n(looping on "+index+")\n");
for(int k=1;k<=3;k++){
// System.out.print("setting i"+index+" to "+k+" ");
set[index] = k;
if (index==2){
dump(set);
}
recurse(index+1, i, list, set);
}
}
return list;
}
static void dump(int[] arr) {
for (int s : arr) {
System.out.format("[%s]", s);
}
System.out.println();
}
}
I'm sorry I had to rewrite the code, but it's pretty much the same algorithm as yours with some corrections:
public class DiceRolls {
static void recurse(int diceNumber, int[] values, final int MAX) {
if (diceNumber == values.length) {
System.out.println(java.util.Arrays.toString(values));
} else {
for (int v = 1; v <= MAX; v++) {
values[diceNumber] = v;
recurse(diceNumber + 1, values, MAX);
}
}
}
public static void main(String[] args) {
recurse(0, new int[3], 4);
}
}
This is a standard tuplet recursive generator. If you want to add all the int[] into a List, then make sure to add(values.clone()) so they are independent int[] objects.
But what's with the extra output?
The problem is that you were dumping prematurely, before you're done throwing all the dices. In pseudocode, this is what you're doing:
if we're not done yet
trying all possibilities for this dice
dump result so far // premature dumping!
recurse for next dice
An easy fix to your code is to do the following:
if we're not done yet
trying all possibilities for this dice
recurse for next dice
else, we're done, so
dump result // timely!
So back to the Java implementation, the fix is merely moving dump(set); to an else case for the if (index < 3) statement.
Call dump() only when index == 2.
Incidentally, i and list seem unused. And the verb is "recur". :)
Here is a non-recursive alternative. Change the two constants to calculate all combinations for different dices and different numbers of dice.
package utils;
public class Dice {
private static int FACES = 3;
private static int NUMBER_OF_DICE = 3;
public static void main(String[] args) {
int start = createPair(1);
int end = createPair(FACES);
for (int i = start; i <= end; i++) {
String combination = Integer.toString(i, FACES+1);
if (combination.indexOf('0') < 0)
System.out.println(combination);
}
}
private static int createPair(int number) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < NUMBER_OF_DICE; i++) {
sb.append(number);
}
return Integer.parseInt(sb.toString(), FACES+1);
}
}

Project Euler (P14): recursion problems

Hi I'm doing the Collatz sequence problem in project Euler (problem 14). My code works with numbers below 100000 but with numbers bigger I get stack over-flow error.
Is there a way I can re-factor the code to use tail recursion, or prevent the stack overflow. The code is below:
import java.util.*;
public class v4
{
// use a HashMap to store computed number, and chain size
static HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
public static void main(String[] args)
{
hm.put(1, 1);
final int CEILING_MAX=Integer.parseInt(args[0]);
int len=1;
int max_count=1;
int max_seed=1;
for(int i=2; i<CEILING_MAX; i++)
{
len = seqCount(i);
if(len > max_count)
{
max_count = len;
max_seed = i;
}
}
System.out.println(max_seed+"\t"+max_count);
}
// find the size of the hailstone sequence for N
public static int seqCount(int n)
{
if(hm.get(n) != null)
{
return hm.get(n);
}
if(n ==1)
{
return 1;
}
else
{
int length = 1 + seqCount(nextSeq(n));
hm.put(n, length);
return length;
}
}
// Find the next element in the sequence
public static int nextSeq(int n)
{
if(n%2 == 0)
{
return n/2;
}
else
{
return n*3+1;
}
}
}
Your problem is not with the size of the stack (you're already memoizing the values), but with
the size of some of the numbers in the sequences, and
the upper limits of a 32-bit integer.
Hint:
public static int seqCount(int n)
{
if(hm.get(n) != null) {
return hm.get(n);
}
if (n < 1) {
// this should never happen, right? ;)
} ...
...
That should hopefully be enough :)
P.S. you'll run into a need for BigNums in a lot of project euler problems...
If you change from integer to long it will give you enough room to solve the problem.
Here was the code that I used to answer this one:
for(int i=1;i<=1000000;i+=2)
{
steps=1;
int n=i;
long current=i;
while(current!=1)
{
if(current%2==0)
{
current=current/2;
}else{
current=(current*3)+1;
}
steps++;
}
if(steps>best)
{
best=steps;
answer=n;
}
}
Brute forcing it, takes about 9 seconds to run
Side note (as it seems that you don't actually need tail call optimization for this problem): tail call optimization is not available in Java, and as far as I have heard, it is not even supported by the JVM bytecode. This means that any deep recursion is not possible, and you have to refactor it to use some other loop construct.
If you are counting the size of the Collatz sequence for numbers upto 1,000,000
you should re-consider using Integer type. I suggest using BigInteger or possible a long.
This should alleviate the problems encountered, but be warned you may still run out of heap-space depending on your JVM.
I think you need these 2 hints :
Don't use Integer because at some starting number, the sequence will fly into some numbers greater than Integer.Max_VALUE which is 2147483647. Use Long instead.
Try not to use recursion to solve this problem, even with memoization. As i mentioned earlier some numbers will fly high and produce a great deal of stacks which will lead into stack overflow. Try using "regular" iteration like do-while or for. Of course you can still use some ingredient like memoization in "regular" loop.
Oh i forget something. Perhaps the stack overflow occurs because of arithmetic overflow. Since you use Integer, maybe Java "change" those "flying numbers" into a negative number when arithmetic overflow occurs. And as seen in method seqCount(int), you don't check invariant n > 0.
You can solve this problem not only with recursion but also with a single loop. there is overflow if you write int. because it generates long while chaning and the recursion never ends because never equal to 1 and you probably get stackoverflow error
Here is my solution with loop and recursion:
public class Collatz {
public int getChainLength(long i) {
int count = 1;
while (i != 1) {
count++;
if (i % 2 == 0) {
i /= 2;
} else {
i = 3 * i + 1;
}
}
return count;
}
public static int getChainLength(long i, int count) {
if (i == 1) {
return count;
} else if (i % 2 == 0) {
return getChainLength(i / 2, count + 1);
} else {
return getChainLength(3 * i + 1, count + 1);
}
}
public int getLongestChain(int number) {
int longestChain[] = { 0, 0 };
for (int i = 1; i < number; i++) {
int chain = getChainLength(i);
if (longestChain[1] < chain) {
longestChain[0] = i;
longestChain[1] = chain;
}
}
return longestChain[0];
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println(new Collatz().getLongestChain(1000000));
}
}
Here you can have a look at my recursive implementation of problem 14:
http://chmu.bplaced.net/?p=265
import java .util.*;
public class file
{
public static void main(String [] args)
{
long largest=0;
long number=0;
for( long i=106239;i<1000000;i=i+2)
{
long k=1;
long z=i;
while(z!=1)
{
if(z%2==0)
{
k++;
z=z/2;
} else{
k++;
z=3*z+1;
}
}
if(k>largest)
{
number=i;
largest=k;
System.out.println(number+" "+largest);
}
}//for loop
}//main
}

Categories