Why is my solution to binomial coefficient crashing? I've really tried to learn recursion, but I still think I am not clear about about it. I wonder if anyone can help me learn about recursion, and how to think recursively?
Even when I write a good base case, my program crashes. Any link to learn recursion with clear demonstration would be very helpful for me.
Here is my code for binomial coefficient, and I'm unable to find the bug/error, looking for your help.
code:
#include<stdio.h>
long long m,n,o,p,result;
long long binomial(long long n,long long m)
{
if(n==m)
return 1;
else {
if(m==0)
return 1;
else {
o=binomial(n-1,m);
p=binomial(n-1,m-1);
return o+p;
}
}
}
int main()
{
printf("Please Enter The Value Of n:\n");
scanf("%lld",&n);
printf("Now Enter The value of m:\n");
scanf("%lld",&m);
result = binomial(n,m);
printf("Resultant Binomial coefficient: %lld\n",result);
return 0;
}
The binomial coefficient is only defined for pairs n and k when n >= k. It is conventional to use n and k in binomial coefficient expressions, but these correspond to n and m in your code.
You need to include some error-checking of input to avoid problems. Your code crashes when n is less than m because each time the statement o=binomial(n-1,m); is executed, the value of n in the called function is reduced, but n is already smaller than m, which is nonzero (if m were zero the function would have simply returned 1), so n == m can never occur.
Incidentally, you can improve your code in a few ways. Using global variables is generally a bad idea, and it would be better to move the declaration:
long long m, n, result;
into main(), where these variables are needed. Also, the function signature for main() should be int main(void). And you can tighten up the logic in the binomial() function considerably, removing the need for o and p:
long long binomial(long long n,long long m)
{
if (m != 0 && n != m) {
return binomial(n-1, m) + binomial(n-1, m-1);
} else {
return 1;
}
}
Related
This is my idea of solving 'nth term of fibonacci series with least processing power'-
int fibo(int n, int a, int b){
return (n>0) ? fibo(n-1, b, a+b) : a;
}
main(){
printf("5th term of fibo is %d", fibo(5 - 1, 0, 1));
}
To print all the terms, till nth term,
int fibo(int n, int a, int b){
printf("%d ", a);
return (n>0)? fibo(n-1, b, a+b): a;
}
I showed this code to my university professor and as per her, this is a wrong approach to solve Fibonacci problem as this does not abstract the method. I should have the function to be called as fibo(n) and not fibo(n, 0, 1). This wasn't a satisfactory answer to me, so I thought of asking experts on SOF.
It has its own advantage over traditional methods of solving Fibonacci problems. The technique where we employ two parallel recursions to get nth term of Fibonacci (fibo(n-1) + fibo(n-2)) might be slow to give 100th term of the series whereas my technique will be lot faster even in the worst scenario.
To abstract it, I can use default parameters but it isn't the case with C. Although I can use something like -
int fibo(int n){return fiboN(n - 1, 0, 1);}
int fiboN(int n, int a, int b){return (n>0)? fiboN(n-1, b, a+b) : a;}
But will it be enough to abstract the whole idea? How should I convince others that the approach isn't wrong (although bit vague)?
(I know, this isn't sort of question that I should I ask on SOF but I just wanted to get advice from experts here.)
With the understanding that the base case in your recursion should be a rather than 0, this seems to me to be an excellent (although not optimal) solution. The recursion in that function is tail-recursion, so a good compiler will be able to avoid stack growth making the function O(1) soace and O(n) time (ignoring the rapid growth in the size of the numbers).
Your professor is correct that the caller should not have to deal with the correct initialisation. So you should provide an external wrapper which avoids the need to fill in the values.
int fibo(int n, int a, int b) {
return n > 0 ? fibo(b, a + b) : a;
}
int fib(int n) { return fibo(n, 0, 1); }
However, it could also be useful to provide and document the more general interface, in case the caller actually wants to vary the initial values.
By the way, there is a faster computation technique, based on the recurrence
fib(a + b - 1) = f(a)f(b) + f(a - 1)f(b - 1)
Replacing b with b + 1 yields:
fib(a + b) = f(a)f(b + 1) + f(a - 1)f(b)
Together, those formulas let us compute:
fib(2n - 1) = fib(n + n - 1)
= fib(n)² + fib(n - 1)²
fib(2n) = fib(n + n)
= fib(n)fib(n + 1) + fib(n - 1)fib(n)
= fib(n)² + 2fib(n)fib(n - 1)
This allows the computation to be performed in O(log n) steps, with each step producing two consecutive values.
Your result will be 0, with your approaches. You just go in recursion, until n=0 and at that point return 0. But you have also to check when n==1 and you should return 1; Also you have values a and b and you do nothing with them.
i would suggest to look at the following recursive function, maybe it will help to fix yours:
int fibo(int n){
if(n < 2){
return n;
}
else
{
return (fibo(n-1) + fibo(n-2));
}
}
It's a classical problem in studying recursion.
EDIT1: According to #Ely suggest, bellow is an optimized recursion, with memorization technique. When one value from the list is calculated, it will not be recalculated again as in first example, but it will be stored in the array and taken from that array whenever is required:
const int MAX_FIB_NUMBER = 10;
int storeCalculatedValues[MAX_FIB_NUMBER] = {0};
int fibo(int n){
if(storeCalculatedValues[n] > 0)
{
return storeCalculatedValues[n];
}
if(n < 2){
storeCalculatedValues[n] = n;
}
else
{
storeCalculatedValues[n] = (fibo(n-1) + fibo(n-2));
}
return storeCalculatedValues[n];
}
Using recursion and with a goal of least processing power, an approach to solve fibonacci() is to have each call return 2 values. Maybe one via a return value and another via a int * parameter.
The usual idea with recursion is to have a a top level function perform a one-time preparation and check of parameters followed by a local helper function written in a lean fashion.
The below follows OP's idea of a int fibo(int n) and a helper one int fiboN(int n, additional parameters)
The recursion depth is O(n) and the memory usage is also O(n).
static int fib1h(int n, int *previous) {
if (n < 2) {
*previous = n-1;
return n;
}
int t;
int sum = fib1h(n-1, &t);
*previous = sum;
return sum + t;
}
int fibo1(int n) {
assert(n >= 0); // Handle negatives in some fashion
int t;
return fib1h(n, &t);
}
#include <stdio.h>
int fibo(int n);//declaring the function.
int main()
{
int m;
printf("Enter the number of terms you wanna:\n");
scanf("%i", &m);
fibo(m);
for(int i=0;i<m;i++){
printf("%i,",fibo(i)); /*calling the function with the help of loop to get all terms */
}
return 0;
}
int fibo(int n)
{
if(n==0){
return 0;
}
if(n==1){
return 1;
}
if (n > 1)
{
int nextTerm;
nextTerm = fibo(n - 2) + fibo(n - 1); /*recursive case,function calling itself.*/
return nextTerm;
}
}
solving 'nth term of fibonacci series with least processing power'
I probably do not need to explain to you the recurrence relation of a Fibonacci number. Though your professor have given you a good hint.
Abstract away details. She is right. If you want the nth Fibonacci number it suffices to merely tell the program just that: Fibonacci(n)
Since you aim for least processing power your professor's hint is also suitable for a technique called memoization, which basically means if you calculated the nth Fibonacci number once, just reuse the result; no need to redo a calculation. In the article you find an example for the factorial number.
For this you may want to consider a data structure in which you store the nth Fibonacci number; if that memory has already a Fibonacci number just retrieve it, otherwise store the calculated Fibonacci number in it.
By the way, didactically not helpful, but interesting: There exists also a closed form expression for the nth Fibonacci number.
This wasn't a satisfactory answer to me, so I thought of asking
experts on SOF.
"Uh, you do not consider your professor an expert?" was my first thought.
As a side note, you can do the fibonacci problem pretty much without recursion, making it the fastest I know approach. The code is in java though:
public int fibFor() {
int sum = 0;
int left = 0;
int right = 1;
for (int i = 2; i <= n; i++) {
sum = left + right;
left = right;
right = sum;
}
return sum;
}
Although #rici 's answer is mostly satisfactory but I just wanted to share what I learnt solving this problem. So here's my understanding on finding fibonacci using recursion-
The traditional implementation fibo(n) { return (n < 2) n : fibo(n-1) + fibo(n-2);} is a lot inefficient in terms of time and space requirements both. This unnecessarily builds stack. It requires O(n) Stack space and O(rn) time, where r = (√5 + 1)/2.
With memoization technique as suggested in #Simion 's answer, we just create a permanent stack instead of dynamic stack created by compiler at run time. So memory requirement remains same but time complexity reduces in amortized way. But is not helpful if we require to use it only the once.
The Approach I suggested in my question requires O(1) space and O(n) time. Time requirement can also be reduced here using same memoization technique in amortized way.
From #rici 's post, fib(2n) = fib(n)² + 2fib(n)fib(n - 1), as he suggests the time complexity reduces to O(log n) and I suppose, the stack growth is still O(n).
So my conclusion is, if I did proper research, time complexity and space requirement both cannot be reduced simultaneously using recursion computation. To achieve both, the alternatives could be using iteration, Matrix exponentiation or fast doubling.
I'm trying to optimize a function that, given an array of N int, return the minimum difference between an element and the previous one. Obviously the function is just for array with a dimension >=2.
For example, given the array {2,5,1}, function returns -4 .
I tried to write my code, but I think it is really intricate.
#include <stdio.h>
#define N 4
/*Function for the difference, works because in the main I already gives one difference*/
int minimodiff(int *a, int n, int diff) {
if (n==1) {
return diff;
}
if (diff>(*(a+1) - *a))
return minimodiff(a+1, n-1, *(a+1)-*a);
else return minimodiff(a+1, n-1, diff);
}
int main() {
int a[N]= {1,8,4,3};
printf("%d", minimodiff(a+1, N-1, *(a+1)-*a));
}
I wonder if there is a way to avoid to pass the first difference in main, but doing everything in the recursive function.
I can use as header file stdio.h / stdlib.h / string.h / math.h . Thanks a lot for the help, I hope that this can give me a better understanding of the recursive functions.
minimodiff(a+1, N-1, *(a+1)-*a) is a weak approach to use recursion for it uses a recursion depths of N which can easily overwhelm system resources depth limit. In such a case, a simple loop would suffice.
A good recursive approach would halve the problem at each call, finding the minimum of the left half and the right half. It may not run faster, but the maximum depth of recursion would be log2(N).
// n is the number of array elements
int minimodiff2(const int *a, size_t n) {
if (n == 2) {
return a[1] - a[0];
} else if (n <= 1) {
return INT_MAX;
}
int left = minimodiff2(a, n/2 + 1); // +1 to include a[n/2] in both halves
int right = minimodiff2(a + n/2, n - n/2);
return (left < right) ? left : right;
}
int main() {
int a[]= {1,8,4,3};
printf("%d", minimodiff2(a, sizeof a/ sizeof a[0]));
}
When doing a min calculation, recursive or otherwise, it makes the initial condition simpler if you set the min to the highest possible value. If you were using floating point numbers it would be Infinity. Since you're using integers, it's INT_MAX from limits.h which is defined as the highest possible integer. It is guaranteed to be greater than or equal to all other integers.
If you were doing this iteratively, with loops, you'd initially set diff = INT_MAX. Since this is recursion, INT_MAX is what gets returned when recursion is done.
#include <limits.h>
static inline int min( const int a, const int b ) {
return a < b ? a : b;
}
int minimodiff( const int *a, const size_t size ) {
if( size <= 1 ) {
return INT_MAX;
}
int diff = a[1] - a[0];
return min( minimodiff(a+1, size-1), diff );
}
The recursive approach is a bad idea because extra memory and function calls are used.
Anyway, your question is about avoiding the first difference.
You can use a centinel.
Since the parameter diff is an int variable, it is not possible to obtain a value greater than INT_MAX.
Thus, your first call to minimodiff can be done by giving the value INT_MAX as the argument corresponding to diff.
Besides, the standard header limits.h must be #include'd at top, to make visible the INT_MAX macro.
I used the following code to generate a simple sieve-
#include<stdio.h>
int main()
{
int a,b,i,j;
scanf("%d%d",&a,&b);
int m = (a)/2;
int d[m+1];
for (i=0;i<m;i++)
d[i]=1;
for (i=1;i<=m;i++)
for (j=i;j<=((m-i)/(2*i+1));j++)
d[i+j+2*i*j]=0;
if (b<=2) printf("2\n");
for (i=0;i<m;i++)
if(d[i]!=0&&i!=0) printf("%d\n",2*(i)+1);
}
but I want to eliminate the extra time used for finding primes upto b, for this I made m = (a-b)/2 and tried starting the main for loop from b/2 and sqrt b/2 instead of zero but it doesn't seem to work, how can I reduce the extra calculation ? Thanks in advance.
So I am trying to do this problem:
However, I'm not entirely sure where to start or what exactly I am looking for.
In addition, I was told I should expect to give the program inputs such as: zero (0), very small (0.00001), and not so small (0.1).
I was given this: http://en.wikipedia.org/wiki/E_%28mathematical_constant%29 as a reference, but that formula doesn't look exactly like the one in the problem.
And finally, I was told that the input to the program is a small number Epsilon. You may assume 0.00001f, for example.
You keep adding the infinite series until the current term's value is below the Epsilon.
But all in all, I have no clue what that means. I somewhat understand the equation on the wiki. However, I'm not sure where to start with the problem given. Looking at it, does anyone know what kind of formula I should be looking to use in C and what "E" is and where it comes into play here (i.e. within the formula, I understand it's suppose to be the user input).
Code So Far
#include <stdio.h>
#include <math.h>
//Program that takes in multiple dates and determines the earliest one
int main(void)
{
float e = 0;
float s = 0;
float ct = 1;
float ot= 1;
int n = 0;
float i = 0;
float den = 0;
int count = 0;
printf("Enter a value for E: ");
scanf("%f", &e);
printf("The value of e is: %f", e);
for(n = 0; ct > e; n++)
{
count++;
printf("The value of the current term is: %f", ct);
printf("In here %d\n", count);
den = 0;
for(i = n; i > 0; i--)
{
den *= i;
}
//If the old term is one (meaning the very first term), then just set that to the current term
if (ot= 1)
{
ct = ot - (1.0/den);
}
//If n is even, add the term as per the rules of the formula
else if (n%2 == 0)
{
ct = ot + (1.0/den);
ot = ct;
}
//Else if n is odd, subtract the term as per the rules of the formula
else
{
ct = ot - (1.0/den);
ot = ct;
}
//If the current term becomes less than epsilon (the user input), printout the value and break from the loop
if (ct < epsilon)
{
printf("%f is less than %f",ct ,e);
break;
}
}
return 0;
}
Current Output
Enter a value for E: .00001
The value of e is: 0.000010
The value of the current term is: 1.000000
In here 1
-1.#INF00 is less than 0.000010
So based on everyone's comments, and using the 4th "Derangements" equation from wikipedia like I was told, this is the code I've come up with. The logic in my head seems to be in line with what everyone has been saying. But the output is not at all what I am trying to achieve. Does anyone have any idea from looking at this code what I might be doing wrong?
Σ represents a sum, so your equation means to compute the sum of the terms starting at n=0 and going towards infinity:
The notation n! means "factorial" which is a product of the numbers one through n:
Each iteration computed more accurately represents the actual value. ε is an error term meaning that the iteration is changing by less than the ε amount.
To start computing an interation you need some starting conditions:
unsigned int n = 0; // Iteration. Start with n=0;
double fact = 1; // 0! = 1. Keep running product of iteration numbers for factorial.
double sum = 0; // Starting summation. Keep a running sum of terms.
double last; // Sum of previous iteration for computing e
double e; // epsilon value for deciding when done.
Then the algorithm is straightforward:
Store the previous sum.
Compute the next sum.
Update n and compute the next factorial.
Check if the difference in the new vs. old iteration exceeds epsilon.
The code:
do {
last = sum;
sum += 1/fact;
fact *= ++n;
} while(sum-last >= e);
You need to write a beginning C program. There are lots of sources on the interwebs for that, including how to get user input from the argc and argv variables. It looks like you are to use 0.00001f for epsilon if it is not entered. (Use that to get the program working before trying to get it to accept input.)
For computing the series, you will use a loop and some variables: sum, current_term, and n. In each loop iteration, compute the current_term using n, increment n, check if the current term is less than epsilon, and if not add the current_term to the sum.
The big pitfall to avoid here is computing integer division by mistake. For example, you will want to avoid expressions like 1/n. If you are going to use such an expression, use 1.0/n instead.
Well in fact this program is very similar to the ones given in the learning to Program in C by Deitel, well now to the point (the error can't be 0 cause e is a irrational number so it can't be calculated exactly) I have here a code that may be very useful for you.
#include <stdio.h>
/* Function Prototypes*/
long double eulerCalculator( float error, signed long int *iterations );
signed long int factorial( int j );
/* The main body of the program */
int main( void )
{
/*Variable declaration*/
float error;
signed long int iterations = 1;
printf( "Max Epsilon admited: " );
scanf( "%f", &error );
printf( "\n The Euler calculated is: %f\n", eulerCalculator( error, &iterations ) );
printf( "\n The last calculated fraction is: %f\n", factorial( iterations ) );
return 1;
}
long double eulerCalculator( float error, signed long int *iterations )
{
/* We declare the variables*/
long double n, ecalc;
/* We initialize result and e constant*/
ecalc = 1;
/* While the error is higher than than the calcualted different keep the loop */
do {
n = ( ( long double ) ( 1.0 / factorial( *iterations ) ) );
ecalc += n;
++*iterations;
} while ( error < n );
return ecalc;
}
signed long int factorial( signed long int j )
{
signed long int b = j - 1;
for (; b > 1; b--){
j *= b;
}
return j;
}
That summation symbol gives you a clue: you need a loop.
What's 0!? 1, of course. So your starting value for e is 1.
Next you'll write a loop for n from 1 to some larger value (infinity might suggest a while loop) where you calculate each successive term, see if its size exceeds your epsilon, and add it to the sum for e.
When your terms get smaller than your epsilon, stop the loop.
Don't worry about user input for now. Get your function working. Hard code an epsilon and see what happens when you change it. Leave the input for the last bit.
You'll need a good factorial function. (Not true - thanks to Mat for reminding me.)
Did you ask where the constant e comes from? And the series? The series is the Taylor series expansion for the exponential function. See any intro calculus text. And the constant e is simple the exponential function with exponent 1.
I've got a nice Java version working here, but I'm going to refrain from posting it. It looks just like the C function will, so I don't want to give it away.
UPDATE: Since you've shown yours, I'll show you mine:
package cruft;
/**
* MathConstant uses infinite series to calculate constants (e.g. Euler)
* #author Michael
* #link
* #since 10/7/12 12:24 PM
*/
public class MathConstant {
public static void main(String[] args) {
double epsilon = 1.0e-25;
System.out.println(String.format("e = %40.35f", e(epsilon)));
}
// value should be 2.71828182845904523536028747135266249775724709369995
// e = 2.718281828459045
public static double e(double epsilon) {
double euler = 1.0;
double term = 1.0;
int n = 1;
while (term > epsilon) {
term /= n++;
euler += term;
}
return euler;
}
}
But if you ever need a factorial function I'd recommend a table, memoization, and the gamma function over the naive student implementation. Google for those if you don't know what those are. Good luck.
Write a MAIN function and a FUNCTION to compute the approximate sum of the below series.
(n!)/(2n+1)! (from n=1 to infinity)
Within the MAIN function:
Read a variable EPSILON of type DOUBLE (desired accuracy) from
the standard input.
EPSILON is an extremely small positive number which is less than or equal to
to 10^(-6).
EPSILON value will be passed to the FUNCTION as an argument.
Within the FUNCTION:
In a do-while loop:
Continue adding up the terms until |Sn+1 - Sn| < EPSILON.
Sn is the sum of the first n-terms.
Sn+1 is the sum of the first (n+1)-terms.
When the desired accuracy EPSILON is reached print the SUM and the number
of TERMS added to the sum.
TEST the program with different EPSILON values (from 10^(-6) to 10^(-12))
one at a time.
have wrote the code for what i see to be a good algorithm for finding the greatest prime factor for a large number using recursion. My program crashes with any number greater than 4 assigned to the variable huge_number though. I am not good with recursion and the assignment does not allow any sort of loop.
#include <stdio.h>
long long prime_factor(int n, long long huge_number);
int main (void)
{
int n = 2;
long long huge_number = 60085147514;
long long largest_prime = 0;
largest_prime = prime_factor(n, huge_number);
printf("%ld\n", largest_prime);
return 0;
}
long long prime_factor (int n, long long huge_number)
{
if (huge_number / n == 1)
return huge_number;
else if (huge_number % n == 0)
return prime_factor (n, huge_number / n);
else
return prime_factor (n++, huge_number);
}
any info as to why it is crashing and how i could improve it would be greatly appreciated.
Even fixing the problem of using post-increment so that the recursion continues forever, this is not a good fit for a recursive solution - see here for why, but it boils down to how fast you can reduce the search space.
While your division of huge_number whittles it down pretty fast, the vast majority of recursive calls are done by simply incrementing n. That means you're going to use a lot of stack space.
You would be better off either:
using an iterative solution where you won't blow out the stack (if you just want to solve the problem) (a); or
finding a more suitable problem for recursion if you're just trying to learn recursion.
(a) An example of such a beast, modeled on your recursive solution, is:
#include <stdio.h>
long long prime_factor_i (int n, long long huge_number) {
while (n < huge_number) {
if (huge_number % n == 0) {
huge_number /= n;
continue;
}
n++;
}
return huge_number;
}
int main (void) {
int n = 2;
long long huge_number = 60085147514LL;
long long largest_prime = 0;
largest_prime = prime_factor_i (n, huge_number);
printf ("%lld\n", largest_prime);
return 0;
}
As can be seen from the output of that iterative solution, the largest factor is 10976461. That means the final batch of recursions in your recursive solution would require a stack depth of ten million stack frames, not something most environments will contend with easily.
If you really must use a recursive solution, you can reduce the stack space to the square root of that by using the fact that you don't have to check all the way up to the number, but only up to its square root.
In addition, other than 2, every other prime number is odd, so you can further halve the search space by only checking two plus the odd numbers.
A recursive solution taking those two things into consideration would be:
long long prime_factor_r (int n, long long huge_number) {
// Debug code for level checking.
// static int i = 0;
// printf ("recursion level = %d\n", ++i);
// Only check up to square root.
if (n * n >= huge_number)
return huge_number;
// If it's a factor, reduce the number and try again.
if (huge_number % n == 0)
return prime_factor_r (n, huge_number / n);
// Select next "candidate" prime to check against, 2 -> 3,
// 2n+1 -> 2n+3 for all n >= 1.
if (n == 2)
return prime_factor_r (3, huge_number);
return prime_factor_r (n + 2, huge_number);
}
You can see I've also removed the (awkward, in my opinion) construct:
if something then
return something
else
return something else
I much prefer the less massively indented code that comes from:
if something then
return something
return something else
But that's just personal preference. In any case, that gets your recursion level down to 1662 (uncomment the debug code to verify) rather than ten million, a rather sizable reduction but still not perfect. That runs okay in my environment.
You meant n+1 instead of n++. n++ increments n after using it, so the recursive call gets the original value of n.
You are overflowing stack, because n++ post-increments the value, making a recursive call with the same values as in the current invocation.
the crash reason is stack overflow. I add a counter to your program and execute it(on ubuntu 10.04 gcc 4.4.3) the counter stop at "218287" before core dump. the better solution is using loop instead of recursion.