简体   繁体   English

递归循环(C#)

[英]Recursive loop (C#)

Can someone please explain it to me? 有人可以向我解释吗? I wrote a function to calculate the factorial of a number like this in C#: 我在C#中编写了一个函数来计算数字的阶乘:

public int factorial(int input)
{
    if (input == 0 || input == 1)
        return 1;
else
{
    int temp = 1;
    for (int i = 1; i <= input; i++)
        temp = temp * i;
    return temp;
    }
}

But I found some C++ code (I don't really know any C++ btw) which finds a factorial using a recursive loop: 但是我发现了一些C ++代码(我真的不知道任何C ++ btw)使用递归循环找到阶乘:

int factorial(int number) {
 int temp;
 if(number <= 1) return 1;
 temp = number * factorial(number - 1);
 return temp;
}

Can someone explain to me how it works? 有人可以向我解释它是如何工作的吗? Thanks. 谢谢。

Well, it uses the fact that factorial(n) is n * factorial(n - 1) with a base case of n = 1 . 好吧,它利用了一个事实,即factorial(n)n * factorial(n - 1) ,基本情况为n = 1

So for example: 因此,例如:

factorial(5) = 5 * factorial(4)
             = 5 * 4 * factorial(3)
             = 5 * 4 * 3 * factorial(2)
             = 5 * 4 * 3 * 2 * factorial(1)
             = 5 * 4 * 3 * 2 * 1

The implementation just uses this recursive definition. 实现仅使用此递归定义。

Lets analyze this line by line: 让我们逐行分析此内容:

if(number <= 1) return 1;
temp = number * factorial(number - 1);
return temp;

Line 1: If the number is less than or equal to zero, we return 1. This is saying that 0! = 1 第1行:如果该数字小于或等于零,则返回1。也就是说0! = 1 0! = 1 and 1! = 1 0! = 11! = 1 1! = 1

Lines 2 + 3: Otherwise we return number * factorial(number - 1) . 第2 + 3行:否则,我们返回number * factorial(number - 1) Lets look at this for 5! 让我们看看这个5! (here i use n! as a synonym for factorial(n) for brevity) (在这里,为了简洁起见,我使用n!作为factorial(n)的同义词)

5!
5 * 4!
5 * 4 * 3!
5 * 4 * 3 * 2!
5 * 4 * 3 * 2 * 1!
5 * 4 * 3 * 3 * 1 // Here we don't have to expand 1! in the same way because of the condition

So the whole thing expands out. 因此,整个事情扩展了。 Its just using the property that 它只是使用的属性

n! = n * (n - 1) * ... * 2 * 1 = n * (n - 1)!

Warning: The recursive code, as always, will suffer from a stack overflow and increased memory usage as compared to an iterative (or tail-recursive-optimized) version, so use at your own risk. 警告:与迭代(或尾部递归优化)版本相比,递归代码将一如既往地遭受栈溢出和内存使用量增加的风险,因此使用风险自负。

Syntactically, the C++ code is identical to the same code written in C#. 从语法上讲,C ++代码与用C#编写的相同代码相同。 Don't let the language discrepancy catch you off guard! 不要让语言差异让您措手不及! It actually looks like C to me, given that the variable is declared at the top of the function; 考虑到变量是在函数顶部声明的,对我来说,它实际上看起来像C。 that's not strictly necessary in either C++ or C#. 无论是C ++还是C#,都不是必须的。 I prefer to declare variables the first time I use them, combining the declaration and initialization in one single statement, but that's merely a stylistic preference that doesn't change the function of the code. 我更喜欢在第一次使用变量时声明变量,将声明和初始化结合在一个单独的语句中,但这只是一种样式偏好,不会改变代码的功能。

I'll try to explain this by adding comments to each line of the code snippet: 我将尝试通过在代码段的每一行中添加注释来解释这一点:

// Declare a function named "Factorial" that accepts a single integer parameter,
// and returns an integer value.
int Factorial(int number)
{
    // Declare a temporary variable of type integer
    int temp;

    // This is a guard clause that returns from the function immediately
    // if the value of the argument is less than or equal to 1.
    // In that case, it simply returns a value of 1.
    // (This is important to prevent the function from recursively calling itself
    // forever, producing an infinite loop!)
    if(number <= 1) return 1;

    // Set the value of the temp variable equal to the value of the argument
    // multiplied by a recursive call to the Factorial function
    temp = number * Factorial(number - 1);

    // Return the value of the temporary variable
   return temp;
}

Recursive calls simply mean that the function calls itself from within the same function. 递归调用仅表示该函数从同一函数内部进行调用。 This works because the factorial of n is equivalent to the following statement: 之所以有效,是因为n的阶乘等效于以下语句:

n! = n * (n-1)! 

One great way to understand how code works is to add it to a test project, then single-step through the code using the debugger. 理解代码工作原理的一种方法是将其添加到测试项目中,然后使用调试器单步执行代码。 Visual Studio has very rich support for this in C# applications. Visual Studio在C#应用程序中对此提供了非常丰富的支持。 You can watch how the function recursively calls itself, watching each line execute in sequence, and even seeing the values of the variables change as operations are performed on them. 您可以观察函数如何递归调用自身,观察每一行按顺序执行,甚至可以看到变量的值随对它们执行的操作而变化。

A recursive function is a function that calls itself in its body. 递归函数是在其主体中调用自身的函数。 For it be bounded, and eventually return a value, two things must happen: 为使其受限制并最终返回值,必须发生两件事:

  1. It has to have a base case where it doesn't call itself again, returning a known value. 它必须具有一个基本情况,即不再调用自身,返回一个已知值。 This base case stops the recursion. 此基本情况将停止递归。 For the factorial function, this value is 1 when the input is 0. 对于阶乘函数,当输入为0时,此值为1。

  2. Its recursive applications must converge to the base case. 它的递归应用程序必须收敛到基本情况。 For factorial, the recursive application calls the function with the input subtracted by 1, which will eventually converge to the base case. 对于阶乘,递归应用程序调用输入减去1的函数,最终将收敛到基本情况。

A simpler way to look at this function is this (only valid for positive input): 查看此功能的更简单方法是:(仅对正输入有效):

int factorial(int input) {
  return input == 0 ? 1 : input * factorial(input - 1);
}

Recursive function are function calling from the same function 递归函数是从同一函数调用的函数

eg: 例如:

  Test()
    {
      i++;
      Test();
      cout<<i;
    }

look at the code it will call the function again and again 看一下代码,它将一次又一次地调用该函数

Problem with recursion it will work infinitely so want to stop it by a particular condition 递归问题将无限发挥作用,因此希望通过特定条件将其停止

some change in above code now look 现在上面的代码有一些变化

int i=0; 
Test()
        {
         if(i==10) return;
         i++;
         Test();
         cout<<i;
        }

output will be 10 printed 10 times, here this line cout<<i; 输出将被10次打印10次,这里cout<<i; will execute after return 返回后将执行

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

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