繁体   English   中英

C递归:return语句

[英]C recursion : return statement

我刚开始学习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;
}

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

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

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

我们发现 :

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

请记住,我们将始终必须找到一个停止的步骤,在这里我们知道

0*y=0

我们完成了。 与@RobertEagle给出的形式相比,这给我们提供了一种更为简单的递归mul函数形式。

但是,让我们更进一步。 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);
}

与第一个方法相比,此方法将花费更少的步骤。 通常,您变得越来越小,变得越来越快。

如果未添加该值,则它将仅返回y作为最递归调用的最终结果。

X * Y = X,Y倍

例如4 * 5 = 4 + 4 + 4 + 4 + 4

这种逻辑正在扩展该求值,并且仅返回最后一个值将仅求值Y一次。

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

  1. 重复条件
  2. 停止条件

没有停止条件,程序将进入无限循环。 在这种情况下,这意味着程序将继续调用x == 1

除了停止在x == 1处调用自身之外,该程序还将调用multiply(-1,y)multiply(-2,y) ...为无穷大。

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

您也可以这样进行:

#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次。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM