Recursion 使用递归求和

Recursion 使用递归求和,recursion,Recursion,我刚刚学习了递归的概念,我想我会尝试一个简单的例子。在下面的代码中,我尝试获取数字:1、2、3、4、5,并使用递归将它们相加。我希望结果是15,但我的代码返回16 我做错了什么 代码: 您在else子句中返回1。您应该返回0: else { return 0; } 如果该值不大于零,为什么首先返回一个?您的代码执行如下: Sum --> 5 Sum --> 4 Sum --> 3 Sum --> 2 Sum -->

我刚刚学习了递归的概念,我想我会尝试一个简单的例子。在下面的代码中,我尝试获取数字:1、2、3、4、5,并使用递归将它们相加。我希望结果是15,但我的代码返回16

我做错了什么

代码:
您在else子句中返回1。您应该返回0:

else
{
    return 0;
}

如果该值不大于零,为什么首先返回一个?

您的代码执行如下:

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

1这是因为,当值为=0时,返回1。然后它被添加


Sum的“else”子句应该返回0。

我很确定问题是因为您希望递归在
value==1
时终止,而当前它在
value==0
终止表达式出现问题时终止。当value==0(或更低)时,它应该返回0而不是1。为了提高效率(我们承认,这显然不是一个问题,否则递归就不会用于此任务),您应该在value==1处终止递归,并返回一个文本1以保存一个不必要的递归级别。

其他人已经注意到了错误,我将详细介绍递归

尽管C#目前没有执行尾部调用优化(尽管IL有特殊的
tail
指令),但值得一提的是,尾部递归通常是一件好事

是递归的一种特殊情况,其中函数的最后一个操作tail调用是递归调用。由于最后一个调用是递归调用,因此不需要保留调用函数的堆栈帧,编译器可以轻松地使用此信息生成机器指令,这样堆栈就不会增长。所以它基本上可以把递归函数变成一个迭代函数

重写代码以支持尾部递归可以按以下步骤进行:

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

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

我总是喜欢把终止案例放在最前面,这样它们就显而易见了,我对
“如果cond然后返回a,否则返回b”
结构有一种近乎心理变态的强烈仇恨。我的选择是(明确表示它对负数不起作用):


我相信这比一堆大括号和控制流更具可读性。

其他人已经回答了这个问题,但当我使用递归时,我喜欢做的一件事是检查它是否有效,即使用检查基本情况和一个附加情况。我会用1测试你的情况,结果是2。因为这显然是错误的,所以您可能需要检查0,因为0不会使用任何递归,因此很明显错误在于基类

一般来说,递归更容易推理,因为你可以列出有限数量的需要检查的东西,但它最初确实需要信念的飞跃,因为你的直觉是错误的。只需测试边缘案例并相信数学,它永远不会失败。

使用系统;
使用NUnit.Framework;
命名空间递归
{
[TestFixture()]
公开课考试
{
[测试()]
公共无效测试和()
{
Assert.AreEqual(和(新的int[]{}),0);
Assert.AreEqual(和(新的int[]{0}),0);
Assert.AreEqual(和(新的int[]{1}),1);
Assert.AreEqual(和(新的int[]{1,2,3,4,5}),15);
}
公共整数和(整数[]头)
{
如果(head.Length==0)返回0;
int[]尾=新的int[head.Length-1];
对于(int i=1;i
也可以这样写:

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

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

    }else{
        total = sum(n-1)+n;
    }
    return total;
}
    // 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; 

    }

事实上,我认为你不需要再检查其他的情况,因为

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
}

从末尾开始,递归求和方法如下所示:

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

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

    }else{
        total = sum(n-1)+n;
    }
    return total;
}
    // 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; 

    }
我希望这有助于深入了解通过递归求和的数字范围。

尝试以下代码:

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

为什么这会得到所有的选票?另一个是正确的,并且是在这一个之前输入的?这是第一个,而且是正确的,由人们来决定他们投票的原因。显然你很难判断时间。@Welbog:+20(和计数)30秒的工作。不错。:-)对你来说就是这样。(对于一个类似的简单问题,我得到+17)当你通过0时,会发生什么?幸好我们生成的是一个和,而不是阶乘。哎呀!忘记。删除了评论并更新了答案:害羞地咧嘴一笑:不要忘记结尾处的
返回值
。你错了,最后一行必须是Sum(结果+1,值-1);Python更容易理解程序的逻辑。这看起来像C#,但为了清晰起见,您能添加一个语言标记吗?希望它能解决问题,但请使用它添加代码解释,以便用户能够完全理解他/她真正想要的。
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
}
    // 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; 

    }
    // 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;

    }
    // version 1

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

        }

        return range;

    }
def sumr(n): 
    if n==0:
        return n
    return n+sumr(n-1)
        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);
        }


    }