Recursive function calls working behind the scenes - c++

So I can't wrap my head around recursive function calls especially with this example:
int Addup(int n)
{
//6
if(n <= 1)
return 1;
else
return n + Addup(n - 1);
/*
6 + 5 + 4 + 3 + 2 + 1
*/
}
Now if for example we did Addup(6), how will that work, what will the program do at runtime? Will it chain all the evaluations after the n then sum them together. I really can't visualize it.
If someone could have a simple way of demonstrating what actually happens at runtime it would be really great.
Thanks in advance.

The secret to understanding recursion is that recursive functions work exactly like non-recursive functions.
Your functions work exactly like these:
int Addup_1(int n)
{
return 1;
}
int Addup_2(int n)
{
if(n <= 1)
return 1;
else
return n + Addup_1(n - 1);
}
int Addup_3(int n)
{
if(n <= 1)
return 1;
else
return n + Addup_2(n - 1);
}
int Addup_4(int n)
{
if(n <= 1)
return 1;
else
return n + Addup_3(n - 1);
}
int Addup_5(int n)
{
if(n <= 1)
return 1;
else
return n + Addup_4(n - 1);
}
int Addup_6(int n)
{
if(n <= 1)
return 1;
else
return n + Addup_5(n - 1);
}

Related

I need to convert this head recursion function to tail recursive

I need to convert this recursive function into tail recursive function but i am getting the wrong output can any help me out with this.
Here is the function definition:
f(n) = 3f(n − 1) - f(n − 2) + n,
with initial conditions f(0) = 1 and f(1) = 2.
#include <iostream>
using namespace std;
int headRecursion(int n) {
if(n == 0) {
return 1;
}
if (n == 1) {
return 2;
}
return 3 * headRecursion(n - 1) - headRecursion(n - 2) + n;
}
int main(){
cout << endl << headRecursion(3);
return 0;
}
This is kind of an interesting problem. We can start with how to implement as a loop:
int minus2 = 1;
int minus1 = 2;
if (n == 0) return minus2;
if (n == 1) return minus1;
for( int i = 2; i <= n; i++)
{
int next = minus1 * 3 - minus2 + i;
minus2 = minus1;
minus1 = next;
}
return minus1;
The takeaway is we need to count UP. In order to make this tail recursive we need to pass in our accumulators (there is no reason to do this other than to show off, but it adds nothing to readability or efficiency)
int tailRecursive(int minus2, int minus1, int step, int n)
{
if (step == n) return minus1;
return tailRecursive(minus1, minus1*3 - minus2 + step+1, step+1, n);
}
you can use an intermediate to set it up and handle the n==0 case.
int calcIt(int n) {
if (n == 0) return 1;
// step must start with 1, since we handled 0 above
return tailRecursive(1, 2, 1, n);
}
Something along these lines:
std::pair<int, int> next_result(std::pair<int, int> prev_result, int n) {
return {3*prev_result.first - prev_result.second + n, prev_result.first};
}
std::pair<int, int> tailRecursion(int n) {
if (n == 0) {
return {1, 0};
}
if (n == 1) {
return {2, 1};
}
return next_result(tailRecursion(n-1), n);
}
int compute(int n) {
return tailRecursion(n).first;
}
int main(){
std::cout << compute(3) << std::endl;
}
Demo
The key is that you need a function that computes a pair {f(n), f(n-1)} given the previously computed pair {f(n-1), f(n-2)}

Bottom-up and memorization of the Fibonacci

I'm made a memorization version of the Fibonacci function (code commented out). Now I want to make a bottom-up and memorization version of the same function. However, my solution seem to be out of the range for really large numbers.
class Solution
{
public:
//Function to count number of ways to reach the nth stair.
int fib(int n)
{
// int memo[n + 1];
// for(int i = 0; i < n + 1; i++) {
// memo[i] = -1;
// }
// if(memo[n] == -1) {
// if(n <= 2) {
// memo[n] = 1;
// } else {
// memo[n] = fib(n - 1) + fib(n - 2);
// }
// }
// return memo[n];
int memo[n + 1];
memo[0] = 1;
memo[1] = 1;
memo[2] = 1;
for(int i = 3; i < n + 1; i++) {
memo[i] = memo[i - 1] + memo[i - 2];
}
return memo[n];
}
// Returns number of ways to
// reach s'th stair
int countWays(int s)
{
int memo[s + 1];
return fib(s + 1);
}
};
example input:
Input:
84
Its Correct output is:
93254120
And Your Code's output is:
-1289228135
You should use uint64_t instead of int to cover wider range of numbers (up to term number 93 which is 12200160415121876738) and avoid this overflow problem, also correct that memo[0] = 0; not 1. Finally, the term number 84 is 160500643816367088 not 93254120.
The prober code for the first method should be like this:
uint64_t fib(int n)
{
if (n < 2)
return n;
else
return fib(n - 1) + fib(n - 2);
}
This code will take long time for later terms.
For the second method:
uint64_t fib(int n)
{
uint64_t *memo = new uint64_t[n + 1];
memo[0] = 0;
memo[1] = 1;
for (int i = 2; i <= n; i++)
memo[i] = memo[i - 1] + memo[i - 2];
return memo[n];
}
This one is much more efficient and faster.

Recursions and functions c++

I have made a function and I am trying to make it recursive. Does anyone have any tips on how I can make this function recursive? I know recursive means to use the function in the function itself.
int countEven(int n){
int evens = 0;
if(n <= 0) return 0; //base case
while(n > 0){
int digit = n%10; //get the last digit
if(digit%2 == 0){
evens = evens + 1;
}
n = n/10;
}
cout << evens;
}
int rec(int n)
{
int sum = 0;
if(n<=0)
return 0;
else if ((n%10)%2==0)
sum = rec(n/10)+1;
else
sum = rec(n/10);
return sum;
}
Maybe something like this :)
For counting the even digits of an integer base 10 you can simplify the function to the following
int countEven(int n)
{
if (n != 0) return !(n % 2) + countEven(n/10);
else return 0;
}
This expands as follows. Assume n = 258:
countEven(258) =
1 + countEven(25) =
1 + 0 + countEven(2) =
1 + 0 + 1 + countEven(0) = 2
Note that the statement !(n % 2) returns 1 if n is even and 0 if it's odd.
For shorter you can do the following:
int ce(int n) { return n ? !(n&1) + ce(n/10) : 0; }
using the ternary operator.
seems like you're trying to count the even digits in a number
int countEven(int n){
if(n == 0)
return 0; //base case
if (n<10)
return !(n%2);
return !(n%2)+countEven(n/10);
}
looks like a similar question i received from QC.
to make it recursive, you must have the function calling onto itself. Ask how you can make the the input simpler and have some sort of base so that the function doesn't break.
int countEven(int number) {
if (x <= 0) return 0;
if (x % 2 == 0) {
return countEven(number / 10) + 1;
}
return countEven(number / 10)
}

Calculate the function F(n) with recursion

Read the topic that I do not know what it is saying:
The function F (n) determined on non-negative integers as follows:
F (0) = 1; F (1) = 1; F (2n) = f (n); F (2n + 1) = F (n) + F (n + 1)
Calculated F (n) by recursion.
and my code:
#include<iostream.h>
double TINH_F(int n)
{
if(n == 0)
{
return 0;
}
if(n == 1)
{
return 1;
}
return (F(n+1) - F(2*n+1));
}
This is obviously incorrect. A recursive function calls itself and includes a stopping condition:
#include<iostream.h>
double TINH_F(int n)
{
if(n == 0)
{
return 0;
}
if(n == 1)
{
return 1;
}
// Note the function name change
return (TINH_F(n+1) - TINH_F(2*n+1));
}
What should your function do if the integer passed in is negative? Will the recursion still work? Or should you throw an exception to indicate to callers that the contract is broken?
int f(int n)
{
if (n<0) return -1; // check if n is positive
if (n<=1) return 1; // we can catch the first two cases in a single condition
int half = n/2;
if (n % 2 == 0) return f(half); // if n is even
else return f(half) + f(half+1); // if n is odd
}
Your last case says
F (n) = F (n+1) + F(2 * n + 1), for all n > 1
If you read the definition carefully, this case is not mentioned anywhere.
I believe you're being tricked by the naming of the parameter - you need four cases.
Let's break it down:
F (0) = 1 (or 0 - your definition says 1, but the code says 0...)
F (1) = 1
F (2n) = F (n)
F (2n + 1) = F (n) + F (n + 1)
The first two cases are trivial.
The third case says that if the argument - let's call it m - is even, the result is F(m/2).
The fourth case says that if the argument m is odd, the result is F(m/2) + F(m/2 + 1).
(Confirming the arithmetic left as an exercise.)
In C++:
unsigned int TINH_F(unsigned int n)
{
if(n == 0)
{
return 1;
}
else if(n == 1)
{
return 1;
}
else if (n % 2 == 0)
{
return TINH_F(n / 2);
}
else
{
return TINH_F(n/2) + TINH_F(n/2 + 1);
}
}

C++ Recursion Segmentation Fault

#include <iostream>
using namespace std;
int findSumofOdds(int n);
int main()
{
int n = 88;
int x;
x = findSumofOdds(n);
cout << x << endl;
return 0;
}
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
n = (n - 1);
return(findSumofOdds(n-1) + 1);
}
else
return 1;
}
Why isn't this recursion working? It tries to run and then crashes. Please let me know. My teacher said that it would work but doesn't.
When n is even, you are decrementing n by two. If it skips over n == 1, it will recurse until it causes a stack overflow. Since n starts out at 88, that's what's happening.
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
n = (n - 1); // <== first decrement
return(findSumofOdds(n-1) + 1); // <== second decrement
}
else
return 1;
}
Also, you seem to be counting the number of odd numbers, not adding them. My guess is that you actually want something like:
int findSumofOdds(int n)
{
if (n != 1)
{
if( n % 2 == 0)
return(findSumofOdds(n - 1));
return(findSumofOdds(n-1) + n); // or + 1 to just count
}
else
return 1;
}
If you want to practice recursion, that's fine. But there's a much simpler way to write a function to sum the odd numbers up to and including n:
int fundSumofOdds(int n) {
n = (n + 1) / 2;
return n * n;
}
This is because there's a general formula:
1 + 3 + 5 + ... + 2n-1 = n2
You have to make it
if (n > 1)
Consider n = 2 here
if (n != 1)
{
if( n % 2 == 0) // Yes
n = (n - 1); // n = 1
return(findSumofOdds(n-1) + 1); // n = 0 <-- will not stop.
and change this too. right now it is just counting the number of odd numbers. You need to sum them.
return(n + findSumofOdds(n - 1));
}
else
return 0;
If you print n in findSumofOdds you can see what is happening -- n becomes negative and you get infinite recursion. If your program doesn't crash earlier, you can get integer overflow (when n goes below the minimum value for int) which yields undefined behavior.
To correct this you can do this:
int findSumofOdds(int n)
{
if(n < 1)
{
return 0;
}
if(n % 2 == 0)
{
return findSumofOdds(n - 1) + 1;
}
return findSumofOdds(n - 2) + 1;
}
You can subtract 2 from n in the last statement, because you only need odd numbers and you know that n can't be even at that point (because of if(n % 2 == 0)).
Also, do you need to find the sum of all odd numbers smaller than n (e.g. 4 (== 1 + 3) for n=5) or do you just need to count them (which is what you are doing now)?
If you want to sum the numbers, you have do add n instead of 1 when returning.