C clarification on recursive functions - c

Hello getting better at C everyday, this is a example problem out of my textbook that generates fibonacci numbers and shows recursive functions. The program works but I just don't understand how... Specifically in parts (looper % 5), the whole functionfib and what printf(", %8ld", fib(looper)); is doing. Is it like saying fib() do x amount of times. If this problem is not easy to explain then could someone show me a easier way to understand how recursive functions work other then "towers of hanoi" example. Thanks.
NOTE: program is meant to handle up to 30 numbers others wise it starts to look ugly.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
long fib (long num);
int main(void)
{
int seriesSize;
printf("This program will print out a Fibonacci series.\n");
printf("How many many numers do you wnat? ");
scanf_s("%d", &seriesSize);
printf("First %d Fib numbers: \n", seriesSize);
for (int looper = 0; looper < seriesSize; looper++)
{
if (looper % 5)
{
printf(", %8ld", fib(looper));
}
else
{
printf("\n%8ld", fib(looper));
}
}
printf("\n");
return 0;
}
long fib(long num)
{
if (num == 0 || num == 1)
{
return num;
}
return (fib(num - 1) + fib(num - 2));
}

The idea behind the long fib(long num) function is that it mirrors the natural definition of the fibonacci sequence in that it is defined in terms of itself. That is, fib(n) is defined by fib(n-1) and fib(n-2). For example, fib(5) is fib(4)+fib(3).
The textbook has written the function in a recursive manner as described above. Note that this is not the most efficient way to implement a fibonacci function but it does logically make sense.
To understand it, it pays to trace through its execution with an example input. Take fib(3) for example. The first if statement doesn't trigger because num is not 0 or 1. Thus, it works out what fib(2) and fib(1) are, and adds them together. We know what fib(1) does - it returns 1 in the first if statement. Trace through fib(2) in a similar manner and you'll see that it returns 1. Thus, fib(3) will return fib(2)+fib(1)=2. You can extend this further - take fib(4). It will return fib(3)+fib(2), which we know are 2 and 1, hence fib(4) = 3.
This approach can be taken for most recursive functions - think of it as creating new instances of the fib() function which continually creates until it "bottoms out" at an end case (num == 1 or num == 0, in this case), and returns back up, filling in the answers until you get back to the function you started with, with the answer.

Related

Write a recursive function to print first N even natural numbers in C

even though I think my syntax is correct, the compiler shows a segmentation fault, and I don't get why.
#include<stdio.h>
void even(int n);
int main() {
even(20);
return 0;
}
void even(int n) {
if (n % 2 == 0) {
even(n - 2);
printf(" %d", n);
}
}
I tried to print even natural numbers using recursions in c, but it does not print anything and just resets my compiler, and when I ran it on an online code runner it displayed a segmentation fault. it would be helpful if someone could point out any syntax errors or explain to me how can I solve this question
It's not that important but still something you need to know...
When you write
the compiler shows a segmentation fault
it's not correct. Compilers don't give segmentation faults for your program. A compiler turns your code into an executable program file (assuming that your code has no syntax errors). The segmentation fault comes when you execute your program if your program is doing something illegal or something that can't be handled by your system.
So what is wrong with your program?
A recursive function must have a condition that makes the recursion stop. In your program there is the condition
if (n % 2 == 0) {
that controls whether recursion shall go on or stop. What this mean is:
if n is even go on with recursive calls
if n is odd stop recursive calls
So calling your even function using an odd value like even(5) will immediately stop recursion, i.e. nothing will be printed at all. That is not what you want...
Calling your even function with an even number like even(20) will give a recursive call.
Your recursive call is
even(n - 2);
Since n is even n - 2 will also be even, i.e. you'll do a recursive call using a new even number as argument. That will lead to yet another recursive call using a new even number as argument. And that will lead to yet another recursive call using a new even number as argument. And that will lead to yet another recursive call using a new even number as argument. And ....
It will never stop! It will go on forever... unless something bad happens - like a segmentation fault for instance.
And that is what happened in your case. The likely explanation is that you ran out of stack memory. Every recursive call used "a little" stack memory and due to doing recursive calls again and again, all stack memory was used and your system responded with a segmentation fault.
You can fix that by changing the condition so that it only accepts values where n is greater than zero. Like
if (n > 0 && n % 2 == 0) {
If you do that you won't get segmentation fault for even(20). The output will be:
2 4 6 8 10 12 14 16 18 20
Unfortunately that is not exactly what you wanted. The code only printed 10 numbers. You wanted it to print 20 numbers. So the "fix" is not fully what you want. And further, odd arguments is still not working.
So it's time to reconsider the program design.
Let's write a recursive function that will do "something" N times.
It could look like:
void even(int n)
{
if (n <= 0)
{
// End recursion
return;
}
printf("Doing something... %d\n", n);
// Do recursive call with decremented argument
even(n - 1);
}
Calling this function with even(5) will generate the output:
Doing something... 5
Doing something... 4
Doing something... 3
Doing something... 2
Doing something... 1
That's not too bad... it did something exactly 5 times as requested. Now we just need to do the right thing, i.e. print the next even natural number. That sound easy but there is a problem... What is the next natural number?
With the current code there is no way of knowing that.. We need to pass some extra information in each recursive call. But we don't want to change the prototype of the function. It has to void even(int n);
The common solution is to introduce a helper function that handles the "extra information" Like:
#include<stdio.h>
void even(int n);
int main()
{
even(5);
return 0;
}
void even_recursive(int next, int n)
{
if (n <= 0)
{
// End recursion
return;
}
printf("next %d\n", next);
// Do recursive call with new next-value and decremented n argument
even_recursive(next + 2, n - 1);
}
void even(int n)
{
even_recursive(2, n);
}
Output
next 2
next 4
next 6
next 8
next 10
The first 5 even natural numbers as required.
BTW:
The even_recursive function can also be written as:
void even_recursive(int next, int n)
{
if (n > 0)
{
printf("next %d\n", next);
even_recursive(next + 2, n - 1);
}
}
to make it a bit shorter.
A recursive routine must have two behaviors:
For some designated “base” case or cases, it performs the desired operation without calling itself.
For other cases, it performs the desired operation in part by calling itself to perform some reduced version of the operation.
Given an even n, your routine never reaches a base case, because, when n is even, n % 2 == 0 is true, and the routine calls itself with even(n - 2), which passes another even number to itself.
Here is a correct version:
void even(int n)
{
if (0 < n)
{
even(n-1);
printf("%d\n", 2*n);
}
}
The base case is when n is zero (or negative). In this base case, the desired operation is to do nothing; zero natural numbers are printed.
The recursive case is when n is positive. In this case, the routine prints the first n even natural numbers in two parts: It calls even(n-1) to print the first n-1 even natural numbers, and then it directly prints the next even natural number.
Main issue is your recursive function for segmentation fault.
A base condition is missing. because of this you're calling function
infinite. Hence you are running out of stack memory. since stack is
finite. In recursion, you need to ensure that you keep calling
function within itself. if you keep calling function itself for
infinite, you run out of stack memory.
some useful link on recursion
Sample code:
#include <stdio.h>
void even(int n);
int main()
{
even(20);
return 0;
}
void even(int n)
{
if(n < 1)
{
return ;
}
else
{
even(n-1);
}
printf("%d ", 2*n);
}
Output:
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40
GDB link for program output, click here
EDIT:
Make correction in to calculate first N-Even Natural number

Fibonacci sequence using recursion in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am trying (and failing) to print the fibonacci sequence using recursion. I'm sure this is very very basic but I can't seem to get it.
Please tell me what I am doing wrong, thanks!
#include <stdio.h>
int fib(int a, int i)
{
int nextnum, num1 = nextnum - 1, num2 = nextnum - 2;
for (i = 0; i >= a; i++) {
nextnum = num1 + num2;
printf("%d", nextnum);
i++;
fib(a, i);
}
}
int main(void)
{
int a, i = 0;
printf("Enter a number for fib series: ");
scanf("%d", &a);
if (a == 1 || a == 2) {
printf("Enter higher number please!\n");
}
else {
fib(a, i);
}
}
Fibonacci numbers are often used as an intro into recursion because they are naturally recursive. In fact, implementing them recursively is trivial in any language. On a side note, it is usually not the best way to implement Fibonacci sequence for practical purposes.
By definition, Fib(X) = Fib(X - 1) + Fib(X - 2). This is recursion right there. The only thing which is missing is how we stop the recursion, and we know that Fib(0) is the same as Fib(1) and is 1.
How do we translate this to the C language? Very simple, almost one-to-one mapping!
unsigned int fib(unsigned int k) {
// First, check our exit (stop) conditions:
if (k == 0 || k == 1) return 1;
// Now recursive part
return fib(k - 1) + fib(k - 2);
}
Almost every recursion function contains two part : the particular part and then the recursive part.
So to write this function your algorithm will look like this
if (condition_separate_particular_part)
{
//here the code for part
}
else
{
//the recursive part
}
Now to determine the recursive part you will try to find how to explain the element "i" using it's predecessor elements "i-1" "i-2" ....
Like this it will be easy for you every time.
Note that sometimes it's useful to start to find iterative way to make it easy for your self.
I'm damn sure that you are new so that's why you feel lost a bit. But trust me you will habit soon if you exercise more. Try and you gonna see. ;).
Let me know if you find difficulties to find more exercises/examples. I will try to help you :).
Here is and example. Just type Exercise with solution for recursive functions on C and you will find a lot to exercise ;).
Now here both recursive and iterative code
Recursive
int fib(int n){
if (n < 2) // here is particular case
return n;
else // here is the recursion
return fib(n-1) + fib(n-2);
}
printf("%d\n", fib(10));
iterative
int fib(int n) {
int first = 0, second = 1;
int tmp;
while (n--) {
tmp = first+second;
first = second;
second = tmp;
}
return first;
}

C - How to trace this recursion?

I've been looking at examples of recursion (in C) online in an attempt to get a better understanding of it and how it works. Generally speaking, I can trace some basic recursion problems without issue (such as a factorial problem), but I found this one and am completely lost on how to trace it.
The idea is that you have the user enter an amount of change, and by using recursion, you print out the number of ways that amount of change can be made. The code is as follows:
#include <stdio.h>
#define NUM_DENOMS 4
int ways(int amount, int denomination);
int main()
{
//Declarations & initializations
int userChange = 0;
//Get user input
printf("Enter an amount you wish to get change for (in cents):\n");// get the amount of change in from the user
scanf("%d", &userChange);
//Function call... pass user's input and denomination values (ints) as parameters
printf("%d cents can be made in %d different ways\n", userChange, ways(userChange, NUM_DENOMS));
return 0;
}
//Function to find # of ways to make change for user's amount
int ways(int amount, int denomination)
{
static int validAmounts[NUM_DENOMS] = {1, 5, 10, 25};
if(denomination<=0) //if denomination is invalid
{
return 0;
}
if((amount == 1) || (amount == 0)) //base case: only 1 combination
{
return 1;
}
else if(amount < 0) //can't have negative amount of money
{
return 0;
}
else //if denomination is valid and user's change > 1
{
return ways(amount, denomination-1) + ways(amount-validAmounts[denomination-1], denomination);
}
}
Apparently this is a common application of recursion. I can't wrap my head around how this recursion works though. What stands out to me the most is the fact that there are 2 recursive calls on the same line. I have never seen recursion applied in this way.
I did attempt to trace it but my results are definitely wrong:
Say I enter 25 as the amount of change. When I go into the ways function, none of the base cases are satisfied and so the recursion comes into play. For the first call, amount stays the same and denomination is decreased by 1, so we go back into the function with 25 and 3 (4-1) as our new arguments. None of the base cases are met until denomination is reduced to 0 (since amount never changes). At this point, we are returning 0. This is the point where I get lost. I see it that 0 gets sent back through all the previous calls and so the end result is 0, but that doesn't sound right to me. I run into the same problem when trying to trace the second call except instead of 0 getting sent back through the calls, it is 1. Obviously my perception of this recursion is horridly wrong. Can someone explain to me how this instance of recursion actually works?
One way to trace a recursive algorithm is to put a printf at the top of the recursive function. The printf should print out the arguments to the function. It's also a good idea to temporarily add more parameters to give yourself additional information about what the recursion is doing. The most common additional parameter is a depth parameter that shows how many nested calls have been made. And for this particular question (where you have two recursive calls) I would add an additional parameter to identify which call is being traced.
With that in mind, here's the modified code. I suggest starting with a simple input, like 5, to get a feel for how the recursion works.
#include <stdio.h>
#define NUM_DENOMS 4
int ways(int amount, int denomination, int left, int depth);
int main( void )
{
int userChange = 0;
printf("Enter an amount you wish to get change for (in cents):\n");
scanf("%d", &userChange);
printf("%d cents can be made in %d different ways\n", userChange, ways(userChange, NUM_DENOMS, 'M', 0));
return 0;
}
int ways(int amount, int denomination, int left, int depth)
{
static int validAmounts[NUM_DENOMS] = {1, 5, 10, 25};
printf( "%2d %d %c %2d\n", amount, denomination, left, depth );
if(denomination <= 0 || amount < 0)
return 0;
if((amount == 1) || (amount == 0))
return 1;
return ways(amount, denomination-1, 'L', depth+1) + ways(amount-validAmounts[denomination-1], denomination, 'R', depth+1);
}
The code makes two calls because it breaks the problem into two parts and each part is solved the same way. Each part is in some sense simpler than the original problem and the same method is used to solve each individual problem. As pointed out by others, there may be situations in which there are more than two parts.
You have likely seen examples with one call where one part of the problem is solved and the single recursive call solves the 'remainder' of the problem.

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.

Simplified vulgar fractions in C

"How to write an algorithm that, given a number n, prints out all the simplified vulgar fractions that have the denominator 1..n"
(I hope I could phrase it well, feel free to rephrase.)
Example: If n is 3, the output should be like "1/2 1/3 2/3"
We were talking about this question in the end of the last class. He showed us a solution and asked us to try to understand the code. Here it is:
#include<stdio.h>
void main()
{
int p,m,n,i,j,a,b;
p=7;
m=0;
n=1;
do
{
printf("%d/%d\n",m,n);
i=j=1;
for(b=2; b<=p; b++)
{
a=m*b/n+1;
if(a*j<b*i)
{
i=a;
j=b;
}
}
m=i;
n=j;
}
while(i<j);
}
I'm new to C and just learning to code, to be honest I couldn't figure out what this code does. And it also prints "0/1", I also wonder why that is, I think it shouldn't be printing that.
Here is my elementary approach to this problem:
#include <stdio.h>
int gcd(int a, int b) // Finds the GCD of two numbers.
{
int temp;
while (a) {
temp = a;
a = b % a;
b = temp;
}
return b;
}
int main(void)
{
int i, j;
for (i = 1; i <= 7; i++) // Denominator goes from 1 to 7
for (j = 1; j < i; j++) // Numerator goes from 1 to denominator
if (gcd(i, j) == 1)
printf("%d/%d ", j, i); // If the numerator and the denominator
// are coprimes then print the fraction
return 0;
}
"n" is 7 in both of the codes. I checked the execution times with much bigger numbers and my algorithm is faster than the other one. So I don't understand what the other code is for. Also any suggestions/corrections about my code is appreciated.
Your professor's code looks like it may have been purposely complicated, maybe as a learning exercise. If that's the case, I can't say I agree with the practice.
Your approach of nested for loops is exactly how I would have approached the solution.
And it also prints "0/1", I also wonder why that is, I think it shouldn't be printing that.
Simply put, it prints "0/1" because of this line:
printf("%d/%d\n",m,n);
The values m and n are initialized to 0 and 1 right before the do loop, so on the first pass it prints exactly that.
Your code is better than the first paste in a few ways. The loop over b is a crappy way of trying to find a common prime factor for m and n. But it only runs to b=7, so the first program can print 11/121 and other non-reduced fractions!
If the loop over b were properly coded, it would take O(sqrt(n)) time. Your gcd() (using the Euclidean Algorithm well) has O(log(n)) time.
The other code is exceptionally poorly written. Single-letter variables for non-idiomatic uses? void main()? No comments? Nobody should be expected to understand that code, and especially not learners.
Your code seems pretty competent - it's far clearer and cleaner than the other code and pretty much superior in every way. The only suggestion I would make is, firstly, you should take in N as user input from the console, to make rerunning the program for different values simpler, and you should also comment the GCD function explaining it's operations.

Resources