could anybody help me to improve this algorithm? It's a recursive function which is basically doing fact(n) * fact(n) but I can't figure out how to make it more efficient.
static long doubleFactorial(int n)
{
if (n == 0)
return 1;
System.out.println("DoubleFactorial(" + n + ") called");
return n * doubleFactorial(n - 1) & doubleFactorial(n - 1);
}
Any help would be much appreciated!
Just save it to a variable and don't call it 2 times:
Here is your code(assuming you want to multiply the factorials and not AND them)
static long doubleFactorial(int n) {
if (n == 0)
return 1;
System.out.println("DoubleFactorial(" + n + ") called");
long fact=doubleFactorial(n - 1);
return n * fact * fact;
}
Also, it would be more efficient if you remove the recursion(but you may not want that):
static long doubleFactorial(int n){
long ret=1;
for(int i=2;i<n;i++){
ret=i*ret*ret;
}
}
This replaces the recursion with a loop what reduces the number of method calls and therefore improves the performance.
Also, it will not create a massive stack(and possibly StackOverflowErrors)
Your logic , doesn't return fact(n) * fact(n)
if you want so, You can define for example :
f(0)=1
f(1)=1
f(2)=2^2*f(1)=4*f(1)
.
.
f(10)=10^2*f(9)
.
.
f(n)=n^2*f(n-1)
So you can use the below code:
static long doubleFactorial(int n)
{
if (n == 0)
return 1;
System.out.println("DoubleFactorial(" + n + ") called");
return n * n * doubleFactorial(n - 1);
}
Try online doubleFactorial(5)=14400
Related
Here we have a formula for elements of sequence: F[i] = 2 * F[i - 1] - cos(i), F[1] = 1.
In the task I should calculate the sum of N elements of the sequence using recursion. I can return the n-idexed element:
public double recursion(int n) {
if (n == 1)
return 1;
else
return (2 * recursion(n - 1) - Math.cos(n));
}
but I don't know how to calculate the sum of that elements. How should I organize this process?
You should first write a method called f that computes the function F[n], which you have done here. You should rename your recursion method to f.
private static double f(int n) {
if (n == 1)
return 1;
else
return (2 * f(n - 1) - Math.cos(n));
}
Then, you write another recursive method called fsum that calculates f(n) + f(n-1) + ... + f(1).
The base case is, of course, 1. When n is 1, fsum should return 1 as well, since f(1) is 1.
Otherwise, return f(n) + the sum of the rest of the f's. What's the sum of the rest of the f's? fsum(n-1)!
public static double fsum(int n) {
if (n == 1) return 1;
return f(n) + fsum(n - 1);
}
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 :)
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
I need a function which can calculate the mathematical combination of (n, k) for a card game.
My current attempt is to use a function based on usual Factorial method :
static long Factorial(long n)
{
return n < 2 ? 1 : n * Factorial(n - 1);
}
static long Combinatory(long n , long k )
{
return Factorial(n) / (Factorial(k) * Factorial(n - k));
}
It's working very well but the matter is when I use some range of number (n value max is 52 and k value max is 4), it keeps me returning a wrong value. E.g :
long comb = Combinatory(52, 2) ; // return 1 which should be actually 1326
I know that it's because I overflow the long when I make Factorial(52) but the range result I need is not as big as it seems.
Is there any way to get over this issue ?
Instead of using the default combinatory formula n! / (k! x (n - k)!), use the recursive property of the combinatory function.
(n, k) = (n - 1, k) + (n - 1, k - 1)
Knowing that : (n, 0) = 1 and (n, n) = 1.
-> It will make you avoid using factorial and overflowing your long.
Here is sample of implementation you can do :
static long Combinatory(long n, long k)
{
if (k == 0 || n == k )
return 1;
return Combinatory(n - 1, k) + Combinatory(n - 1, k - 1);
}
EDIT : With a faster iterative algorithm
static long Combinatory(long n, long k)
{
if (n - k < k)
k = n - k;
long res = 1;
for (int i = 1; i <= k; ++i)
{
res = (res * (n - i + 1)) / i;
}
return res;
}
In C# you can use BigInteger (I think there's a Java equivalent).
e.g.:
static long Combinatory(long n, long k)
{
return (long)(Factorial(new BigInteger(n)) / (Factorial(new BigInteger(k)) * Factorial(new BigInteger(n - k))));
}
static BigInteger Factorial(BigInteger n)
{
return n < 2 ? 1 : n * Factorial(n - 1);
}
You need to add a reference to System.Numerics to use BigInteger.
If this is not for a homework assignment, there is an efficient implementation in Apache's commons-math package
http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/ArithmeticUtils.html#binomialCoefficientDouble%28int,%20int%29
If it is for a homework assignment, start avoiding factorial in your implementation.
Use the property that (n, k) = (n, n-k) to rewrite your choose using the highest value for k.
Then note that you can reduce n!/k!(n-k)! to n * n-1 * n-2 .... * k / (n-k) * (n-k-1) ... * 1 means that you are multiplying every number from [k, n] inclusive, then dividing by every number [1,n-k] inclusive.
// From memory, please verify correctness independently before trusting its use.
//
public long choose(n, k) {
long kPrime = Math.max(k, n-k);
long returnValue = 1;
for(i = kPrime; i <= n; i++) {
returnValue *= i;
}
for(i = 2; i <= n - kPrime; i++) {
returnValue /= i;
}
return returnValue;
}
Please double check the maths, but this is a basic idea you could go down to get a reasonably efficient implementation that will work for numbers up to a poker deck.
The recursive formula is also known as Pascal's triangle, and IMO it's the easiest way to calculate combinatorials. If you're only going to need C(52,k) (for 0<=k<=52) I think it would be best to fill a table with them at program start. The following C code fills a table using this method:
static int64_t* pascals_triangle( int N)
{
int n,k;
int64_t* C = calloc( N+1, sizeof *C);
for( n=0; n<=N; ++n)
{ C[n] = 1;
for( k=n-1; k>0; --k)
{ C[k] += C[k-1];
}
}
return C;
}
After calling this with N=52, for example returns, C[k] will hold C(52,k) for k=0..52
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.