Computing some recursive functions in C - c

I am beginner at recursive function concepts..I have 2 problems to ask:
Given: f(n) = n/2 if n is even, f(3n+1) if n is odd.
How can I write a recursive function to compute f(n)?
What problem do you notice in the following recursive function? Show 2 possible ways to correct it.
int silly(int n )
{
if (n<= 0)
return 1;
else if (n%2==0)
return n;
else
silly(n-3);
}

f(n) = n/2 if n is even, f(3n+1) if n is odd.
A recursive function to do that is something like this pseudo-code:
def f(n):
if f % n == 0: return f(n/2) # assume integer division.
return f(3*n-1)
However, given that every integral number is either even or odd (even and odd have no meaning but for integers), then there's no terminating condition. You'll soon run out of stack space, unless your compiler is smart enough to turn that recursive function into an iterative one, in which case you'll run for eternity.
The usual problem statement of that type has a terminating condition like "stop when it reaches zero", which would be the following modification:
def f(n):
if n == 0: return 0
if f % n == 0: return f(n/2)
return f(3*n-1)
In fact, usually you're required to measure the number of operations to reach zero, which would be:
def f(n, count):
if n == 0: return count
if f % n == 0: return f(n/2, count+1)
return f(3*n-1, count+1)
In terms of the recursive function, the problem is that not all paths return a value. You can fix that by ensuring they do. This can be done by simply prefixing silly (n-3) with return but, since I prefer not to have all those unnecessary if/else blocks, it's cleaner to write like this:
int silly (int n) {
if (n <= 0) return 1;
if (n % 2 == 0) return n;
return silly (n-3);
}

Related

Where do recursive functions end?

#include <stdio.h>
int factorial(int n);
void main()
{
int n;
printf("Enter your number : " );
scanf("%d",&n);
if(n <= 1)
{
printf("The factorial of the number n is ",n);
}
else
{
int res = factorial(n);
printf("The result is %d\n",res);
}
}
int factorial(int n)
{
if(n <= 1)
return 1;
return n * factorial(n-1);
}
I'm doing a recursive function concept for the first time and i pretty much got like a 65% grasp on the concept of recursion. In the above program i have written a factorial recursion function and it goes normally well and i get the output but i'm trying to think where the recursion ends
Like for example i have gave an input of 5 :
The result is 120
but the main thing i wanted is why it doesn't continue after 0, if n <= 1(given if n = 0,-1...and so on during recursion) and then it should keep on returning "1" and multiplying with the recursion function(the factorial function being called inside the "factorial" function).In conclusion I really have no idea where the recursion ends...can you please clear it up.
Lets say you have call factorial(3), then the call-chain will be something like this:
factorial(3) // Initial call
factorial(2);
factorial(1);
return 1; // No more recursion
return 2 * 1; // 1 is the result of factorial(1)
return 3 * 2; // 2 is the result of factorial(2)
The result of factorial(3) will be 6 (3 * (2 * 1)).
In conclusion I really have no idea where the recursion ends..
It ends at the return 1; statement:
int factorial(int n)
{
if(n <= 1)
return 1; <---- Here
return n * factorial(n-1);
}
Maybe it's more clear if you wrote it like:
int factorial(int n)
{
if(n <= 1)
{
// No more recursive calls - just return 1
return 1;
}
else
{
// Do recursive call with decremented argument
return n * factorial(n-1);
}
}
So the code keeps doing recursive calls until n becomes 1. Then it returns 1 to the previous recursive call which returns 2 (2 * 1) to the previous recursive call which returns 6 (3 * 2) to the previous recursive call which returns 24 (4 * 6) .... and so on.
So the final result is calculated like:
1 * 2 * 3 * 4 * ...
\---/
2 * 3
\-------/
6 * 4
\-----------/
24
From Recursion:
In mathematics and computer science, a class of objects or methods exhibits recursive behavior when it can be defined by two properties:
A simple base case (or cases) — a terminating scenario that does not use recursion to produce an answer.
A recursive step — a set of rules that reduces all successive cases toward the base case.
So, terminating scenario('s)/condition('s) is one of property of recursion and it's where the recursion ends.
In context of your program:
Your program is finding the factorial of a given number n.
The factorial of a non-negative integer n is the product of all positive integers less than or equal to n:
n ! = n * ( n − 1 ) * ( n − 2 ) * ( n − 3 ) * ..... * 3 * 2 * 1
which is equivalent to
n ! = n * ( n - 1 ) !
that means, when writing program to calculate the factorial of a number n, we have to calculate the product of all positive integers and stop when reached to 1, which is the terminating condition.
In factorial() function:
int factorial(int n)
{
if(n <= 1)
return 1;
return n * factorial(n-1);
}
The condition if(n <= 1) is the terminating condition for recursive function finding the factorial of n and its where the recursive function factorial() ends.
Additional:
In your program, you are missing the format specifier in this
printf() statement:
printf("The factorial of the number n is ",n);
it should be
printf("The factorial of the number n is %d\n",n);
^^
Note that, 0! is 1 and, after making above change, your program
will give output as 0 when user give input number 0 which is
wrong.
May you should write function to calculate factorial of given positive number n like this:
unsigned int factorial(unsigned int n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
and add a check on user input before calling factorial(). This will take care of 0! as well.
Using void as return type of main function is not as per
standards. The return type of main function should be int.
To understand simple recursive code, it helps a lot to draw a diagram (recursive trace). I will draw it in paint, but it's even better to do it on paper. Let's say we are calling factorial(3).
Write down the call of the function. (In the beginning, it's factorial(3))
Ask yourself: "Is the exit condition satisfied?" (In your case the condition is if(n <= 1))
If the answer is yes, check what gets returned and write it under the previous function call, then go to the next step. You have return 1; so 1 gets returned.
If the answer is no, check what gets returned and write it under the previous function call. You have return n*factorial(n-1); so the first time the return value will be 3*factorial(3-1), which is equal to 3*factorial(2). Now go back to step 1) with the new function call and repeat the process until the condition is satisfied. The call here is factorial(2). You can also connect the function calls with arrows to make the diagram more organized.
This is how the diagram should look like when your condition is satisfied:
You now go from the bottom upwards:Write down the value of the very bottom function call, and repeat for every function call above that. In your case, you first write the value of factorial(1), which is 1, then you move up, and you see that factorial(2) is equal to 2*factorial(1). And because you know that factorial(1) is equal to 1, you also know that
factorial(2) is equal to 2.
You can connect the function calls upwards to make the diagram more organized.
You are done. The diagram should look something like this:
With this diagram, we know exactly when the recursion stops - when factorial(1) is called. We also know the end result, which is 6.

How is it possible to achive O(log n) power function a^n by only using recursion?

Below, the purpose of the code is to compute power of an integer.
My friend told me that the time complexity of this algorithm is O(log n).
But, in fact the number of function calls is not equal to logn.
For example, power(2, 9) calls power functions 5 times (including the calling power(2,9)), while power(2, 8) calls power function 4 times (including the calling power(2,8).
Nevertheless the number of bits needed for 8 and 9 are same, the numbers of function calls are different.
Why does this happen? Is this really O(log n) algorithm?
#include <stdio.h>
int power(int a, int n) {
if(n == 0) {
return 1;
}
if(n == 1) {
return a;
}
if (n%2 == 0) {
return power(a*a, n/2);
}else{
return a * power(a, n - 1);
}
}
int main() {
for (int i = 0; i < 15; i++)
printf("pow(%d, %d) = %d\n", 2, i, power(2, i));
return 0;
}
Your implementation is O(logN), but it could be made slightly more efficient.
Note that hereafter, a log is a log base 2.
You have log(n) calls of power(a*a,n/2), and a call to power(a, n-1) for every bit set in n.
The number of bits set in n is at most log(n) +1.
Thus, the number of calls to power is at most log(n)+log(n)+1. For instance, when n = 15, the sequence of calls is
power(15), power(14), power(7), power(6), power(3), power(2), power(1)
log(n)+log(n)+1 = 3+3+1 = 7
Here is a more efficient implementation that has only log(n)+2 calls of power.
int power(int a, int n) {
if(n == 0) {
return 1;
}
if (n&1 == 0) {
return power(a*a, n/2);
}else{
return a * power(a*a, n/2);
}
}
In this case the sequence of calls when n = 15 is
power(15), power(7), power(3), power(1), power(0)
I removed the if (n == 1) condition because we can avoid this test that would be performed log(n) time by adding one call to power.
We then have log(n)+2 calls to power which is better than 2log(n)+1.
The reason why the algorithm remains Ο(lgN) even with the extra calls for the odd number case is because the number of extra calls is bounded by a constant. In the worst case, N/2 is odd at each iteration, but this would only double the number of extra calls (the constant is 2). That is, at worst, there will be 2lgN calls to complete the algorithm.
To more easily observe that the algorithm is Ο(lgN), you can rewrite the function to always reduce the power by half at each iteration, so that at worst case, there are only lgN calls. To leverage tail recursion, you can add a function parameter to accumulate the carried multiplier from the odd N.
int power_i (int a, unsigned N, int c) {
if (N == 0) return c;
return power_i(a*a, N/2, N%2 ? a*c : c);
}
int power (int a, unsigned N) {
return power_i(a, N, 1);
}
The advantage of tail recursion is that the optimized code will be converted into a simple loop by most modern C compilers.
Try it online!
The power function has two base cases: n = 0 and n = 1.
The power function has two recursive calls. Only one of them is made in any given call.
Let's first consider the case when n is even: In that case, the recursive call is made with n / 2.
If all calls would use this case, then you half n in each call down until you reach 1. This is indeed log(n) calls (plus 1 for the base case).
The other case, when n is odd, reduces n only by one. If all calls would end up using this recursive call then the function would be called n times; clearly not logarithmic but linear thus.
But what happens to an odd number when you subtract one from it? It becomes an even number. Thus the feared linear behaviour mentioned above cannot occur.
Worst case is: n is odd, thus use second recursive call. Now n is even, thus first recursive call. Now n is odd, this use second, ... and so on down until n is one. In that case every second call reduces n to n / 2. Therefore you need 2 * log(n) calls then (plus one for the base case).
So yes, this is in O(log(n)). This algorithm is often called binary exponentiation.

Working on a Fibonnaci/mysequence code

I was working on a code that is suppose to calculate the sequence:
a(n+2)=-2(n+1)+3a(n) a(0)=2 a(1)= -1
Unfortunately I cannot figure it out. I'm recently new at this (about a month) and I'm going to try best to do this on my own, but I will need some help. Thank you for whoever decides to help me.
#include <stdio.h>
int mysequence(int n)
{
if (n==0) return 2;
if (n==1) return -1;
if (n==2) return 8;
return (2 * mysequence(n+1) + mysequence(n+2))/3;
}
int main()
{
int n;
printf("Enter n = ");
scanf("%d", &n);
printf("%d\n",mysequence(n));
return 0;
}
I'm not sure how you came up with this line:
return (2 * mysequence(n+1) + mysequence(n+2))/3;
But that's not correct. For one thing, mysequence(n) would call mysequence(n+1) (and mysequence(n+2)), which would call mysequence(n+2), which would call mysequence(n+3), which would call mysequence(n+4), etc. - it should be easy to see that you'll never reach mysequence(0) or mysequence(1) (assuming n > 1), thus it would keep going forever, or at least until you run out of memory, since you're increasing instead of decreasing the parameter in subsequent calls.
Let's start from the beginning by first converting this:
a(n+2) = -2a(n+1) + 3a(n)
Into something that looks more like the code: (by subtracting 2 from each n+c)
(on the left side we'd like a(n), since the function takes the parameter n, not n+2)
a(n) = -2a(n-1) + 3a(n-2)
Now we simply need to put that in the code. Replace:
return (2 * mysequence(n+1) + mysequence(n+2))/3;
With
return -2 * mysequence(n-1) + 3 * mysequence(n-2);
Also, you don't really need to specifically cater for n == 2 - it will be handled correctly by the above statement.
The n will be more bigger until unlimited number when run your program.
I think you need change the function to :
a(n)=-2(n-1)+3a(n-2) a(0)=2 a(1)= -1
Replace n+2 with n. It will make n smaller until 1 and 0.
Then code will be:
int mysequence(int n)
{
if (n == 0) return 2;
if (n == 1) return -1;
return (-2 * mysequence(n - 1) + mysequence(n - 2)) / 3;
}
note: n >= 0
Look at the line return (2 * mysequence(n+1) + mysequence(n+2))/3 carefully and compare it with what you know about the sequence:
a(n+2)=-2(n+1)+3a(n).
They have nothing in common.
What you want is return (-2*mysequence(n-1) + 3*mysequence(n-2)).
As to why, well the coefficients should be clear enough, they are just copied from the definition. The reason we call the next level of recursion with n-1 and n-2 is also quite simple, observe:
a(n+2)=-2(n+1)+3a(n) -> substitute n for n-2 -> a(n)=-2(n-1)+3a(n-2).
Your recursive function is infinitely so! The value of n passed in is incremented in the recursive calls, but the base cases for the recursion assume they decrease.
You'll need what is called a change of variables. Let m = n + 2. So n = m - 2. Then the recurrence you've given becomes
a(m) = -2 * (m - 1) + 3 * a(m - 2)
Implement this as a recursive function. Since the value passed as the argument on the right hand side is now less than that the left, the small base case values will be reached for any m >= 0.

finding greatest prime factor using recursion in c

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.

Incorrect output from recursive function to compute sum of digits of a number

I was trying to write a function that would compute the sum of the digits of a number using recursion, but the output is incorrect. Here's the code:
/*Write a function to calculate sum of digits of a number using recursion*/
/*Author:Udit Gupta Date:10/08/2011*/
#include<stdio.h>
int sum (int);
int main () {
int n,s;
printf ("Enter the number:");
scanf ("%d",&n);
s = sum (n);
printf ("The sum of the digits of the number is %d",s);
}
int sum (int a) {
int f;
if (a == 0) {
return f;
}
f = (a% 10) + sum (a/10);
}
Here are some of the output values:
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:123
The sum of the digits of the number is 7
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:1234
The sum of the digits of the number is 2919930
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:123456
The sum of the digits of the number is 4620297
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:12345
The sum of the digits of the number is 15 /*Only this one seems correct*/
Can someone help me figure out why this isn't working correctly?
Let's look at this recursive function in more detail:
int sum (int a) {
int f;
if (a == 0)
return f;
f = (a% 10) + sum (a/10);
}
While you're on the right track and you have the right idea in general, your actual implementation is a bit buggy. For starters, let's look at these lines:
if (a == 0)
return f;
You have the right idea to terminate the recursion when a reaches zero, but the way you're doing it is a bit off. In particular, you're returning the value of the integer f, but you've never initialized it. This means that the return value is completely arbitrary. Instead of writing this, I think that you probably meant to write something closer to
if (a == 0)
return 0;
which correctly says "if the number is zero, the sum of its digits is zero."
Similarly, take a look at the last line of your function:
f = (a% 10) + sum (a/10);
Again, your intuition is spot-on: the sum of the digits of a number are given by the sum of its first digit and the sum of the rest of its digits. However, notice that while you're correctly computing the sum of the digits, you aren't correctly returning the sum of the digits. In fact, you don't return anything at all if you execute this code, so the return value from the function is unspecified, hence the garbage output. To fix this, consider rewriting the code like this:
return (a % 10) + sum (a / 10);
This actually says to hand back the value that you just generated right here, instead of storing it in a local variable that will be immediately cleaned up as soon as the function returns.
I believe that the reason you coded this function this way is that you're under the impression that the value of int f; is carried across the function calls. Unfortunately, it is not. When writing a recursive function, each instance of the function is completely independent of each other instance and local variables accessible in one recursive call are not accessible in other recursive calls. Consequently, even though each recursive call has its own variable int f, those variables are all completely independent of one another. The value isn't carried through them. If you want to communicate values across recursive functions, the best way to do it is by using the return value of the recursive calls, or (if you must) by passing a pointer to some value down through the recursion.
Hope this helps!
When a is 0, you are returning an uninitialized value (f was not initialized).
Change it to:
if (a == 0)
return 0;
You also forgot the return in the end of the function:
return (a% 10) + sum (a/10);
It is highly recommended that you always compile with the flag -Wall, which would warn you about those mistakes.
Your recursive function will calculate nothing it either returns an uninitialized int or nothing. You need to be returning the work you are doing in the function.
int sum (int a) {
if (a == 0) {
return 0;
}
return (a% 10) + sum(a/10);
}
return a == 0 ? 0 : ((a% 10) + sum (a/10));
You only return f is it is 0, but not if it isn't, which makes your return value undefined. I assume you want to do:
int sum (int a) {
int f;
if (a == 0)
return 0;
f = (a % 10) + sum (a / 10);
return f;
}

Resources