-2

I have to count sum 1/1+1/2+1/3+1/4+1/n series using recursion. I have tried this but it does not work. how should I solve it?

#include<iostream>
using namespace std;
double sum(int n)
{
  if(n==1){return 1;}
  if(n==0){return 0;}
  return 1+1/sum(n-1);
}
int main(){
  cout<<sum(2);
}
1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
YoungCoder
  • 3
  • 1
  • 3

2 Answers2

0

As others already pointed out in the comments, the formula in your function results in another series than the intended harmonic series. Here, a possible solution:

#include <iostream>
using namespace std;

double sum_recursive(int n)
{
    if (n <= 0) {
        return 0.0;
    } else {
        cout << "1/" << n << (n!=1 ? " + " : " = "); // just for debugging
        return (1.0 / double(n)) + sum_recursive(n-1);
    }
}

double sum_iterative(int n)
{
    double v = 0.0;
    if (n <= 0) {
        return 0.0;
    }
    for (int i=n; i>0; --i) {
        v += 1.0 / double(i);
        cout << "1/" << i << (i!=1 ? " + " : " = "); // just for debugging
    }
    return v;
}

int main()
{
    const int x = 4;
    cout << sum_iterative(x) << " (iterative)" << endl;
    cout << sum_recursive(x) << " (recursive)" << endl;
    return 0;
}

Console:

$ g++ test_seq.c && ./a.out
1/4 + 1/3 + 1/2 + 1/1 = 2.08333 (iterative)                                                                                                                                         
1/4 + 1/3 + 1/2 + 1/1 = 2.08333 (recursive)

Assuming this is just used as an exercise, it should be noted, that a recursive solution doesn't have any apparent advantages over a simple loop...

rel
  • 764
  • 5
  • 18
0

There are several ways you can approach this. While recursive functions can provide elegant solutions for some problem where a non-recursive approach is difficult, recursion in general should not be your first choice. Why? Each recursive call is a separate function call that requires the setup and resources of a complete function stack. If you recurse too many times, you will actually learn about StackOverflow...

That said, learning recursive functions are a necessary part of learning to program. Here the number of recursive calls is limited to n so you are safe. Every recursive function has two things:

  1. an exit condition that stops the recursion; and
  2. a recursive call.

You want to preserve a sum over your recursive calls. A static variable initialized on its first declaration will do. So in this case, you can do something like:

double sum (int n)
{
    static double val = 0.;
    
    if (n) {
        val += 1. / n;
        sum (n - 1);
    }
    
    return val;
}

The scheme above is relatively simple. You use a check for a positive value for n as your exit condition, and each time you make a recursive call you reduce the value of n by 1. If you want to see how your recursion is progressing, you can add debug output between the update of val and the recursive call to sum (n - 1) such as:

        std::cout << "n:" << n << "  frac: 1/" << n << "  val: " << val << '\n';

A short example that takes the first argument to the program as n could be:

#include <iostream>
#include <string>

double sum (int n)
{
    static double val = 0.;
    
    if (n) {
        val += 1. / n;
        sum (n - 1);
    }
    
    return val;
}

int main (int argc, char **argv) {
    
    /* initialize with 1st argument to program (default: 2) */
    std::string s { argc > 1 ? argv[1] : "2" };
    int n;
    
    try {                                   /* stoi must have exception handler */
        n = stoi (s);                       /* attempt conversion */
        std::cout << sum (n) << '\n';       /* output result */
    }
    catch (const std::exception & e) {      /* catch exception return error */
        return 1;
    }
}

Example Use/Output

The resulting values for n from 0 to 20 would be:

$ for i in {0..20}; do printf "%2d  " $i; ./bin/frac_sum_recurse $i; done
 0  0
 1  1
 2  1.5
 3  1.83333
 4  2.08333
 5  2.28333
 6  2.45
 7  2.59286
 8  2.71786
 9  2.82897
10  2.92897
11  3.01988
12  3.10321
13  3.18013
14  3.25156
15  3.31823
16  3.38073
17  3.43955
18  3.49511
19  3.54774
20  3.59774

While you are building good habits learning C++, have a look at: Why is “using namespace std;” considered bad practice?. Here it would save no more than three std::.

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Just to get the terminology right: stack frame != full stack. – HAL9000 Mar 08 '21 at 21:44
  • Is `if (n)` still considered good practice for C++? It feels flaky relying on the binary representation of the integer value of 0 being the same as for the boolean value false. – Eric J. Mar 08 '21 at 23:38
  • 1
    @EricJ. It's really six-to-one, a half-dozen-to-another. `if (n)` is simply shorthand for `if (n == 0)`. (or int the case of a pointer, `NULL` or `nullptr`). There is no prohibition to using either, but for readability, there is an argument that `n == 0` form is more explicitly readable. – David C. Rankin Mar 09 '21 at 01:17