14

I have just been studying the concept of recursion and I thought that I would try a simple example. In the following code, I am attempting to take the numbers: 1, 2, 3, 4, 5, and add them together using recursion. I expected the result to be 15, but my code is returning 16.

What am I doing wrong?

Code:

    static void Main(string[] args)
    {
        
        Console.WriteLine(Sum(5));
        Console.Read();
    }


    static int Sum(int value)
    {
        if (value > 0)
        {
          return value + Sum(value - 1);
        }
        else
        {
            return 1;
        }
    }
1
  • This looks like C#, but could you add a language tag for clarity? Commented Jan 7, 2018 at 5:14

16 Answers 16

35

You're returning 1 in the else clause. You should be returning 0:

else
{
    return 0;
}

If the value is not greater than zero, why would you return one in the first place?

Sign up to request clarification or add additional context in comments.

5 Comments

why would this get all the up votes? the other are correct and were entered before this one?
It was first, and it's right, and it's up to people to decide why they vote.
Apparently you have trouble telling time.
@Welbog: +20 (and counting) for 30 seconds work. Nice one. :-)
That's SO for you. (I got +17 for a simimlar simple question)
19

Your code executes as follows:

Sum --> 5
  Sum --> 4
    Sum --> 3
      Sum --> 2
        Sum --> 1
          Sum --> 0
          1 <---
        2 <---
      4 <---
    7 <---
  11 <---
16 <---

Check your base case.

Comments

14

Others already noted the error, and I will elaborate on recursion.

Although C# does not currently perform tail call optimization (although IL has special tail instruction), it's worth mentioning that tail recursion is generally a good thing.

Tail recursion is a special case of recursion in which the last operation of the function, the tail call, is a recursive call. Since the last call is the recursive call there is no need to preserve stack frame of the calling function and the compiler can easily use this information to generate machine instruction such that the stack doesn't grow at all. So it can basically turn recursive function into an iterative one.

Rewriting your code to support tail recursion can be done as follows:

static int Sum(int result, int value)
    {
        if (value == 0)
            return result;

        return Sum(result + value, value - 1);
    }

2 Comments

Don't forget the return at the end.
You're wrong the last line has to be Sum(result + 1, value - 1);
7
static int Sum(int value)
{
    if (value > 0)
    {
        return value + Sum(value - 1);
    }
    else
    {
        return 0; //Change this.
    }
}

3 Comments

And, when you pass in zero, what happens?
Good thing we're generating a sum and not a factorial.
Oops! Forgot. Deleted the comment and updated the answer :sheepish grin:
5

That's because, when the value is = 0, you return 1. Then it get's added.

Sum's "else" clause should return 0.

Comments

4

I always prefer to put the terminating case(s) up front so they're obvious, and I have a violent near-psychopathic hatred of "if cond then return a else return b" constructs. My choice would be (making it clear that it won't work properly for negative numbers):

static unsigned int Sum(unsigned int value) {
    if (value == 0)
        return 0;
    return value + Sum(value - 1);
}

I believe that's far more readable than a morass of braces and control flow.

Comments

4

The others have already answered that question, but when I work with recursion, one of the things I like to do to check that it works is to use check the base case and one additional case. I your case I would test it with 1, which would yield 2. Since this is obviously wrong you might want to check for 0 which is not going to use any recursion and so it should be obvious that the error lies in the base class.

In general recursion is easier to reason about, since you can list the limited number of things you need to check, but it does initially require a leap of faith since your intuition will be wrong. Just test the edge cases and trust the math it will never fail.

Comments

4
int summation(int num){

    if (num==1)
        return 1;

    return summation(num-1)+num;
}

Comments

1

I'm pretty sure the problem is because you want your recursion to terminate when value == 1, and it's currently terminating when value == 0.

Comments

1

Your terminating expression is at issue. When value == 0 (or lower), it should return a 0 rather than 1. For sake of efficiency (which, let's admit it here, obviously isn't a concern, otherwise recursion wouldn't have been used for this task), you should terminate the recursion at value == 1 and return a literal 1 to save one unnecessary level of recursion.

Comments

0
using System;
using NUnit.Framework;

namespace Recursion
{
  [TestFixture()]
    public class Test
    {
        [Test()]
        public void TestSum ()
        {
            Assert.AreEqual (Sum (new int[] { }), 0);
            Assert.AreEqual (Sum (new int[] { 0 }), 0);
            Assert.AreEqual (Sum (new int[] { 1 }), 1);
            Assert.AreEqual (Sum (new int[] { 1, 2, 3, 4, 5 }), 15);
        }

        public int Sum(int[] head)
        {
            if (head.Length == 0) return 0;

            int[] tail = new int[head.Length - 1];

            for (int i = 1; i < head.Length; i++) 
            {
                tail [i-1] = head [i];
            }

            return head[0] + Sum (tail);
        }
    }
}

Comments

0

It could also be written like this:

public static int sum(int n){
    int total;

    if(n==1){
        total =1;

    }else{
        total = sum(n-1)+n;
    }
    return total;
}

Comments

0

Actually, I think you don't need to check case else because

public static int sum(int number){
    if(number > 0){
       return number + sum(--number);
    }
    return number; // return 0 so that's why you don't need check else condition
}

Comments

0

To begin at the end, a recursive Sum method looks like this:

    // version 3

    public static int Sum(int startRange, int endRange)
    {
        if (endRange > startRange)
        {
            return endRange + Sum(startRange, endRange - 1);

        }

        if (endRange < startRange)
        {
            return startRange + Sum(endRange, startRange - 1);

        }

        return endRange; 

    }

Hardcoding the startRange to be 0 gives us:

    // version 2

    public static int Sum(int range)
    {
        if (range > 0)
        {
            return range + Sum(0, range - 1);

        }

        if (range < 0)
        {
            return Sum(range, -1);

        }

        return range;

    }

...and if you want to limit the method to positive numbers only, there's no need for a sign:

    // version 1

    public static unsigned int Sum(unsigned int range)
    {
        if (range > 0)
        {
            return range + Sum(0, range - 1);

        }

        return range;

    }

I hope this helps give more of an insight into summing number ranges via recursion.

Comments

0
        static int Sum(int[] addends)
    {
        if (addends.Length == 1)
        {
            return addends[0];
        }
        else
        {
            int tailIndex = addends.Length - 1;
            var subArray = addends[0..tailIndex];
            return addends[tailIndex] + Sum(subArray);
        }


    }

1 Comment

Hope It will solve issue but please add explanation of your code with it so user will get perfect understanding which he/she really wants.
-2

Try this code:

def sumr(n): 
    if n==0:
        return n
    return n+sumr(n-1)

1 Comment

Python is more easy to understand logic of programs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.