as a beginner in programming I am trying to convert the following recursive method to an iterative one but I just don't get the hang of it. The method or function has a binary tree like recursion and I would like to use an array for the iterative solution.. unfortunately I am very confused how to do it.
I have already checked the way of converting the fibonnaci recursive method to an iterative one. But I think this is not the same here. Also I am not sure if a tree search method is useful?! Any help, hint, idea would be appreciated. Thanks.
public static int funct(int n) {
if (n == 0) return 1;
if (n == 1) return 2;
if n > 1 return funct(n-2)*funct(n/2);
}
Since every n-th member is computed by others before if you can cache all in a list. You start by adding the first 2 known members. Fibonacci its easier because you always need only previous value.
private static int func(int n) {
List<Integer> values = new ArrayList<>(n+1);
values.add(1);
values.add(2);
for (int i = 2; i <= n; i++) {
values.add(values.get(i - 2) * values.get(i / 2));
}
return values.get(n);
}
Now the real function is without last if:
public static int funct(int n) {
if (n == 0) return 1;
if (n == 1) return 2;
return funct(n-2) * funct(n/2);
}
As the recursive calls refer to smaller parameters one can cache all return values upto n.
Unfortunately this already spoils the pleasure, as the resulting code is complete:
public static int funct(int n) {
int[] results = new int[n+1];
results[0] = 1;
results[1] = 2;
int i = 2;
while (i <= n) {
results[i] = results[i-2] * results[i/2];
++i;
}
return results[n];
}
It indeed looks like fibonacci.
In general one would not need to fill all items of results. like probably results[n - 1].
Unfortunately you should have learnt prior to this problem:
Solving tail recursion.
Using a stack (like here) to use inner results of a recurive call.
You might look into those topics.
Math afterlude
The initial values are powers of 2. As the result is a product of earlier results, all results will be powers of 2.
f(0) = 1 = 2^0
f(1) = 2 = 2^1
f(n) = f(n - 2) * f(n / 2)
Hence you can introduce:
g(0) = 0
g(1) = 1
g(n) = g(n - 2) + g(n / 2)
f(n) = 2^g(n)
This will enlarge the range you can calculate as say 2100.
You will also see:
g(2k + 1) = g(2k) + 1
So you will only need a domain of even numbers:
g(2k) = g(2(k-1)) + g(k - k%2) + k%2
Related
I'm very new to programming, just learned it in university. I have a task where I have to solve this problem recursively in java (without using arrays, if, else, while, etc...)
So the task is to sort numbers from 13542 to 12345.
public static void main(String[] args) {
System.out.println(sort(13542));
}
public static long sort(long n) {
return n < 10
? n
: sort(n, 0);
}
public static long sort(long n1, long n2) {
return n1 > 10
? xxx
: xxx;
}
The problem is that I have no idea what to do. I think my start is okay, but I have problems with the second method.
Firstly, recursion means, put simply, that you have something call itself repeatedly. The fact that the assignment is on recursion is a hint of how your lecturer wants you to solve it, using a recursive method.
Ignoring the main for now, since while it could be prettied up and made more elegant, that isn't the core of the problem.
public int recursiveSort(int toSort){
}
And for neatness, we'll want a method to check if it is sorted, and to do the sorting.
public Boolean isSorted(int toCheck){
//TODO: Check if input is sorted
}
public int singleSort(int toSort){
//TODO: Sorting algorithm
}
Which gives us a recursive method of
public int recursiveSort(int toSort){
toSort = singleSort(toSort);
return isSorted(toSort) ? toSort : recursiveSort(toSort);
}
The sorting with the constraints imposed is the tricky part, and depends on exactly what you cannot use.
And of course, try to look at different sorting algorithms and consider how you would implement them in this case.
Here's a pure recursion with one function and one argument; without log, power, string conversion or loops. I'd say this is quite a difficult exercise in recursion even for more than a beginner. I hope this helps. Feel free to ask for any clarification. (Simplifications are also welcome.)
JavaScript code:
function main() {
console.log(sort(13542));
}
function sort(n) {
if (n < 10)
return n;
let r = n % 10;
let l = (n - r) / 10 % 10;
let sorted = sort(Math.floor(n / 10) - l + r);
let last = sorted % 10;
if (l < last)
return 10 * sort(sorted - last + l) + last;
else
return 10 * sorted + l;
}
main();
Every recursive method should include 2 main "ingredients":
A termination condition
A step forward
As you've mentioned, the obvious termination condition is that a number has only 1 digit, which means it's sorted (and therefore the recursion should stop).
The necessary progression of the method would be to remove a digit on every run, sort the smaller number and then merge the digits together.
As you can figure, the actual challenge can be either merging correctly, or separating efficiently.
I chose to locate the maximal digit, remove it from the original number and send the newly created number back into the recursive function. Eventually the method merges the sorted digits with the largest digit on their right.
public static void main(String[] args) {
System.out.println(sort(13542));
}
public static long sort(long n) {
// For testing purposes:
// System.out.println("sort(" + n + ")");
if (n < 10) return n; // Termination condition
int numOfDigits = (int)(Math.log10(n)+1);
long largestDigit = n % 10;
long restOfDigits = n / 10;
for(int i=0; i<numOfDigits; i++) {
long current = (long) (n / Math.pow(10, i)) % 10;
if (current > largestDigit) {
largestDigit = current;
restOfDigits = (long) Math.pow(10, i) * (n / (long) Math.pow(10, i + 1))
+ (n % (long) Math.pow(10, i));
}
}
// Merge the largest number on the right
return 10 * sort(restOfDigits) + largestDigit;
}
As you can see, for testing purposes it's best to check the recursive method on its beginning. You can either print or use a debugger to see its progression.
In it's simplest form, recursion is making a method call itself over and over. Here's a simple example.
public void eatAllFoodFromTable(Table tbl, Person prsn) {
if(tbl.hasFood()) {
prsn.sustain(1);
tbl.removeFood(1);
eatAllFoodFromTable(tbl, prsn); /*As you can see here,
the method calls itself. However, because the method has a condition
that can prevent it from running indefinitely (or a way to terminate),
it will repeat until the condition is met, then terminate. This is recursion!*/
} else {
//Do nothing.
}
}
What you want to do is take your long, and feed it into a method called sort, or similar. Then, that method will check to see if some of it is in order (through some kind of iteration), and then call itself (sort()) again with the new long generated from the sorting iteration.
Upon reaching the point where it is sorted, the method will terminate, returning the final sorted value.
Thanks alot for your help. I think I got it now:
public static long sort(long n) {
return n < 10
? n
: shuffle(sort(n / (long) Math.pow(10, count(n) / 2)),
sort(n % (long) (Math.pow(10, count(n) / 2))));
}
public static long count(long n) {
return n < 10
? 1
: 1 + count(n / 10);
}
public static long shuffle(long n1, long n2) {
return (n1 > 0 || n2 > 0)
? (n1 % 10 > n2 % 10)
? shuffle(n1 / 10, n2) * 10 + n1 % 10
: shuffle(n1, n2 / 10) * 10 + n2 % 10
: 0;
}
Sadly we weren't allowed to use if, else or while. This would have been so much easier. But thank you all :)
I have this code below, I would like to know how to calculate the number of swaps. I used a count variable to figure it out, but I was getting different number than the computer. I figure the number of swaps would be 2 * (n - 1)(n - 2)...(n - n + 1). For n == 4, the computer got 128, and I got 48. What am I doing wrong?
public void permute(int n) {
if (n == 1) {
printOutPut();
}
for (int i = 1; i <= n; i++){
swap(i, n);
permute1(n-1);
swap(i, n);
}
}
The code defines a recursion:
num_swaps(0) = 0
num_swaps(i) = i * (num_swaps(i - 1) + 2)
or with more math-like symbols:
s_{n+1} = (n + 1) (s_n + 2)
s_0 = 0
s_1 = 2
s_2 = 8
s_3 = 30
s_4 = 128
You can probably solve that recursion for a general n using techniques from maths, but this verifies that the computer is right
Edit: I was trying to find a solution for general n, ended up on wolfram alpha and the solution presented had incomplete gamma functions and stuff. So, don't expect the calculation to be easy!
I was given a beginner assignment based on recursion to calculate the product of any given base and power.
My professor wanted us to use recursion to calculate this using three different methods..
I've done the first two with little problem, however the final recursive function is giving me grief.
(for method power4)
• X^n = ( X^ (n / 2)^2 if n > 0 and n is even
• X^n = X * ( X^ (n / 2)^2 if n > 0 and n is odd
all I need to do is raise power4(x, (n/2)) to the power of 2
I am not allowed to call the math class... I can't think of anyway to raise this function to the power of 2, any help would greatly be appreciated.
PS: I would prefer help or an explanation rather than just the answer if possible
Thanks.
I just need help with the method power4, power2 and power3 already work fine.
CODE:
public int power2(int x, int n)
{
if(n == 0)
answer = 1;
else if (n > 0)
answer = x * power2(x, (n - 1));
return answer;
}
public int power3(int x, int n)
{
if(n == 0)
answer = 1;
else if(n % 2 == 0)
answer = power3(x, (n/2)) * power3(x, (n/2));
else
answer = x * power3(x, (n/2)) * power3(x, (n/2));
return answer;
}
public int power4(int x, int n)
{
if(n == 0)
answer = 1;
//incomplete code from here down
else if (n % 2 == 0)
answer =
else
answer = x *
return answer;
}
Raising a value to the power of two, a.k.a. squaring it, is simply multiplying it by itself. However, DON'T multiply two recursive calls to the function - do something like
result = power4(x, n/2);
answer = result * result;
Then, if it's odd, multiply answer by x.
If you were to try doing this as answer = power4(x, n/2) * power4(x, n/2);, you'd be doubling the amount of work at each level of the recursion by calling the function twice, and completely undo the logarithmic run time.
By the way, are you sure one of your cases isn't supposed to be based on xn = (x2)n/2 or xn = x*(x2)n/2 for n even or odd, respectively? As you've described it, it looks like power3 and power4 are the same.
This might help with raising to the power of 2:
int answer = 0;
for (int i = 0; i < x; i++)
{
answer += x;
}
public class Prod {
public static void main(String[] args) {
System.out.println(prod(1, 4));
}
public static int prod(int m, int n) {
if (m == n) {
return n;
} else {
int recurse = prod(m, n-1);
int result = n * recurse;
return result;
}
}
}
On running the above code , I get 24 ?
I don't quite understand how?
My doubts:
1. When m =1 , n=4 , we call prod until m and n become equal to 1.
Then the output should be n and else block should not be executed??
Someone please help me understand the logic.
Just run through this with the numbers, you need to write it down to see the behavior exactly (in the future, I suggest adding lots of prints to your code to check variables and how they change with each pass through).
prod(1,4)
m=1,n=4
m != n so, recurse = prod(1, 3)
prod(1, 3)
m=1,n=3
m != n so, recurse = prod(1, 2)
prod(1, 2)
m=1,n=2
m != n so, recurse = prod(1, 1)
prod(1, 1)
m=1,n=1
m == n so,
return 1
returns to prod(1, 2)
recurse = 1
result = 2 * 1
return 2
returns to prod(1, 3)
recurse = 2
result = 3 * 2
return 6
returns to prod(1, 4)
recurse = 6
result = 4 * 6
return 24
Thus, your program prints 24.
Sometimes the best way to figure out a program is to mechanically go through the steps line by line, executing them in your head (or on paper to track things).
To understand any program with functions, you assume the called functions do their job right, and check that the calling function calls them in the correct order with the correct arguments, and combines the results correctly.
For recursive functions you need to check that each recursive call gets you closer to the case in which there is no recursion.
Here nobody told us what is the result supposed to be. The recursion ends whenever m == n, and the recursive call is with n = n - 1, so this will work only if m <= n.
Consider a string of calls, each one reduces n by 1, while m stays fixed. Say n == m + 3 for finding out what happens: The first call gets m + 2, the second m + 1, the third m, and returns m. The second takes n == m + 1 by m returned by the third, the second takes n == m + 2 and multiplies by the previous result, and finally the result is (m + 3) * (m + 2) * (m + 1) * m. This function computes n! / (m - 1)!, if n >= m. Knowing that this is what is going on, it is easy to check that our (up to now just) hunch is right.
prod(1, 4);
public static int prod(int m, int n) {
if (m == n) {
return n;
} else {
int recurse = prod(m, n-1);
int result = n * recurse;
return result;
}
}
can be transformed with m == 1 to:
prodA(4);
public static int prodA(int n) {
if (1 == n) {
return n;
} else {
int recurse = prodA(n-1);
int result = n * recurse;
return result;
}
}
which has a transformation (head recursion):
public static int prodA(int n) {
int result = 1;
while (n > 1) { // Actually n != 1
result *= n;
--n;
}
return result;
}
which is the factorial function.
I was just going through the iterative version of fibonacci series algorithm. I found this following code
int Fibonacci(int n)
{
int f1 = 0;
int f2 = 1;
int fn;
for ( int i = 2; i < n; i++ )
{
fn = f1 + f2;
f1 = f2;
f2 = fn;
}
}
A silly question just raised in my mind. The function above adds two previous numbers and returns the third one and then get variables ready for the next iteration. What if it would be something like this. "Return a number of series which is the sum of previous three numbers" how we can change the above code to find such a number.u
As a hint, notice that the above algorithm works by "cycling" the numbers through some variables. In the above code, at each point you are storing
F_0 F_1
a b
You then "shift" them over by one step in the loop:
F_1 F_2
a b
You then "shift" them again in the next loop iteration:
F_2 F_3
a b
If you want to update the algorithm sum the last three values, think about storing them like this:
T_0 T_1 T_2
a b c
Then shift them again:
T_1 T_2 T_3
a b c
Then shift them again:
T_2 T_3 T_4
a b c
Converting this intuition into code is a good exercise, so I'll leave those details to you.
That said - there is a much, much faster way to compute the nth term of the Fibonacci and "Tribonacci" sequences. This article describes a very clever trick using matrix multiplication to compute terms more quickly than the above loop, and there is code available here that implements this algorithm.
Hope this helps!
I like recursion. Call me a sadist.
static int rTribonacci (int n, int a, int b, int c) {
if (n == 0) return a;
return rTribonacci (n-1, b, c, a + b + c);
}
int Tribonacci (int n) { return rTribonacci(n, 0, 0, 1); }
I don't normally answer questions that "smell" like homework, but since someone else already replied this is what I would do:
int Tribonacci(int n)
{
int last[3] = { 0, 0, 1 }; // the start of our sequence
for(int i = 3; i <= n; i++)
last[i % 3] = last[i % 3] + last[(i + 1) % 3] + last[(i + 2) % 3];
return last[n % 3];
}
It can be improved a bit to avoid all the ugly modular arithmetic (which I left in to make the circular nature of the last[] array clear) by changing the loop to this:
for(int i = 3; i <= n; i++)
last[i % 3] = last[0] + last[1] + last[2];
It can be optimized a bit more and frankly, there are much better ways to calculate such sequences, as templatetypedef said.
If you want to use recursion, you don't need any other parameters:
int FibonacciN(int position)
{ if(position<0) throw new ArgumentException("invalid position");
if(position==0 || position ==1) return position;
return FibonacciN(position-1) + FibonacciN(position-2);
}