简体   繁体   English

C递归:return语句

[英]C recursion : return statement

I just started learning C and I faced the following problem: in the first / recursive step / I do not understand why we cannot simply return multiply(x, y) ? 我刚开始学习C,却遇到了以下问题:在第一步/ 递归步骤中 /我不明白为什么我们不能简单地返回乘法(x,y) Why do we need to add a value to y and only then return it? 为什么我们需要向y添加一个值,然后才返回它?

The code is below. 代码如下。 Thank you! 谢谢!

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

If you return multiply(x, y) , you will loop forever on the same call parameters. 如果返回乘法(x,y) ,则将在相同的调用参数上永远循环。 To have proper recursion, you have to reduce the problem to a simpler case. 为了进行适当的递归,您必须将问题简化为更简单的情况。 That simpler case is to reduce the multiplier by 1. 最简单的情况是将乘数减1。

Recursion is simply doing the same operations with smaller inputs. 递归只是使用较小的输入执行相同的操作。 Can we express multiplication of two numbers with smaller numbers ? 我们可以用较小的数字表示两个数字的乘法吗? Sure ! 当然可以! Finding the way to do this is finding a recursive definition of multiplication. 找到做到这一点的方法是找到乘法的递归定义。 First we will try to express x*y with a smaller x, like x-1. 首先,我们将尝试用较小的x(如x-1)表示x * y。 From the simple fact that : 从简单的事实来看:

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

we find : 我们发现 :

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

Remember that we will always have to find a stoping step, here we know that 请记住,我们将始终必须找到一个停止的步骤,在这里我们知道

0*y=0

and we're done. 我们完成了。 This gives us even a simpler form of a recursive mul function as the one given by @RobertEagle. 与@RobertEagle给出的形式相比,这给我们提供了一种更为简单的递归mul函数形式。

But let us take the thing further. 但是,让我们更进一步。 x-1 is smaller than x, as y-1 is smaller than y. x-1小于x​​,因为y-1小于y。 Exploring this fact gives us : 探索这个事实使我们:

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

This time the stopping step would be "if x or y is 0 then the result is 0". 这次停止步骤将是“如果x或y为0,则结果为0”。 Translating this into code : 将其转换为代码:

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

This sort of recursion is not quite efficient because we do not express the recursion with something really smaller. 这种递归效率不高,因为我们没有用更小的东西来表示递归。 What if we try to halve one of the parameters ? 如果我们尝试将参数之一减半怎么办? If x is even we can write : 如果x是偶数,我们可以写:

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

If x is odd we can write : 如果x是奇数,我们可以写:

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

Multiplying (resp. dividing) by 2 can be achieved with left (resp. right) shifting : 左移(分别为右)可实现乘以(分别为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);
}

This method will take less steps than the first one. 与第一个方法相比,此方法将花费更少的步骤。 The "more" you're getting smaller, the "more" you're getting faster, in general. 通常,您变得越来越小,变得越来越快。

If you didn't add the value, it would simply return y as the final result of the top most recursive call. 如果未添加该值,则它将仅返回y作为最递归调用的最终结果。

X * Y = X, Y times X * Y = X,Y倍

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

This logic is expanding that evaluation, and just returning the last value would only evaluate to Y one time. 这种逻辑正在扩展该求值,并且仅返回最后一个值将仅求值Y一次。

Every recursive function is made up of 2 elements: 每个递归函数都由2个元素组成:

  1. The repetitive condition 重复条件
  2. The stopping condition 停止条件

Without a stopping condition, the program would enter an infinite loop. 没有停止条件,程序将进入无限循环。 In this case, it would mean the program would continually call beyond x == 1 . 在这种情况下,这意味着程序将继续调用x == 1

Instead of stopping calling itself at x == 1 , the program would also call multiply(-1,y) , multiply(-2,y) ... to infinite. 除了停止在x == 1处调用自身之外,该程序还将调用multiply(-1,y)multiply(-2,y) ...为无穷大。

Ultimately, you need to sum the y for x times. 最终,您需要将y相加x倍。 And to do this you need to return x times the value of y . 为此,您需要返回x乘以y的值。 And in this case, the repetitive condition adds y for x-1 times and for the stopping condition you only need one more time. 在这种情况下,重复条件将y加 x到1倍,对于停止条件,您只需要再增加一次。

You also could have done it this way: 您也可以这样进行:

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

Here you can see the repetitive is concerted with adding the y for exactly x times. 在这里,您可以看到重复项与y恰好相加x倍。 Logically, the stopping condition would require to return 0, because we don't need to add anymore the y value. 从逻辑上讲,停止条件需要返回0,因为我们不再需要添加y值。 We already have added it for x times. 我们已经添加了x次。

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

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