C递归:return语句

时间:2016-07-12 23:03:47

标签: c recursion

我刚刚开始学习C,我遇到了以下问题: 在第一个 / 递归步骤 / 我不明白为什么我们不能简单地返回乘(x,y)?为什么我们需要为y添加一个值,然后才返回它?

代码如下。 谢谢!

#include <stdio.h>

unsigned int multiply(unsigned int x, unsigned int y)
{
    if (x == 1)
    {
        /* Terminating case */
        return y;
    }
    else if (x > 1)
    {
        /* Recursive step */
        return y + multiply(x-1, y);
    }

    /* Catch scenario when x is zero */
    return 0;
}

int main() {
    printf("3 times 5 is %d", multiply(3, 5));
    return 0;
}

4 个答案:

答案 0 :(得分:2)

如果您返回乘(x,y),您将永远循环使用相同的调用参数。要进行适当的递归,您必须将问题简化为更简单的情况。更简单的情况是将乘数减少1。

答案 1 :(得分:1)

递归只是使用较小的输入执行相同的操作。我们能用较小的数字表示两个数的乘法吗?好的!找到这样做的方法是找到乘法的递归定义。首先,我们将尝试使用较小的x表示x * y,如x-1。 从简单的事实来看:

(x-1)*y = x*y - y

我们发现:

x*y=(x-1)*y + y

请记住,我们总是必须找到一个停止步骤,我们知道

0*y=0

我们已经完成了。这给了我们一个更简单的递归mul函数形式,就像@RobertEagle给出的那样。

但是让我们更进一步。 x-1小于x​​,因为y-1小于y。探索这个事实让我们:

(x-1)*(y-1)=x*y-x-y+1
x*y = (x-1)*(y-1) + x + y - 1

这次停止步骤为“如果x或y为0则结果为0”。将其翻译成代码:

unsigned multiply(unsigned x, unsigned y)
{
  if ( (x==0) || (y==0) )
    return 0;
  else
    return x+y-1+multiply(x-1, y-1);
}

这种递归效率不高,因为我们没有用更小的东西来表达递归。如果我们尝试将其中一个参数减半怎么办? 如果x是偶数,我们可以写:

x*y=2*(x/2)*y=(x/2)*(2*y)

如果x是奇数,我们可以写:

x*y=(x-1+1)*y=(x-1)*y+y=((x-1)/2)*(2*y)+y

左(右)右移可以实现乘以(分为右)2:

unsigned multiply(unsigned x, unsigned y)
{
  if (x==0)
    return 0;
  else if (x%2==0)
    return multiply(x>>1, y<<1);
  else
    return y+multiply((x-1)>>1, y<<1);
}

此方法比第一步采用更少的步骤。一般而言,“越多”越小,“越多”越快。

答案 2 :(得分:0)

如果您没有添加该值,则只会返回y作为最高递归调用的最终结果。

X * Y = X,Y次

e.g。 4 * 5 = 4 + 4 + 4 + 4 + 4

这个逻辑正在扩展该评估,只返回最后一个值只能评估为Y一次。

答案 3 :(得分:0)

每个递归函数由2个元素组成:

  1. 重复条件
  2. 停止条件
  3. 没有停止条件,程序将进入无限循环。 在这种情况下,这意味着该计划将不断调用x == 1

    该程序不会停止在x == 1处自行调用,而是会将multiply(-1,y)multiply(-2,y) ...调用为无限。

    最终,您需要将 y x 相加。要做到这一点,您需要返回 x 乘以 y 的值。在这种情况下,重复条件为 x-1 次添加 y ,对于停止条件,您只需要再多一次。

    你也可以这样做:

    #include <stdio.h>
    
    unsigned int multiply(unsigned int x, unsigned int y)
    {
        if (x == 0)
        {
            /* Terminating case */
            return 0;
        }
        else if (x > 0)
        {
            /* Recursive step */
            return y + multiply(x-1, y);
        }
    }
    
    int main() {
        printf("3 times 5 is %d", multiply(3, 5));
        return 0;
    }
    

    在这里,您可以看到重复性与 y 完全相同的 x 时间相加。从逻辑上讲,停止条件需要返回0,因为我们不需要再添加 y 值。我们已经为 x 次添加了它。