有人可以向我解释一下吗?我写了一个函数来计算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;
}
}
但是我找到了一些C ++代码(我真的不知道任何C ++ btw),它使用递归循环找到了一个阶乘:
int factorial(int number) {
int temp;
if(number <= 1) return 1;
temp = number * factorial(number - 1);
return temp;
}
有人可以向我解释它是如何工作的吗?感谢。
答案 0 :(得分:6)
嗯,它使用的事件factorial(n)
为n * factorial(n - 1)
,基本情况为n = 1
。
例如:
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
实现只使用这个递归定义。
答案 1 :(得分:2)
让我们逐行分析:
if(number <= 1) return 1;
temp = number * factorial(number - 1);
return temp;
第1行:如果数字小于或等于零,我们返回1.这就是说0! = 1
和1! = 1
第2 + 3行:否则我们返回number * factorial(number - 1)
。让我们看一下5!
(这里我使用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
所以整个事情扩大了。它只是使用
的属性 n! = n * (n - 1) * ... * 2 * 1 = n * (n - 1)!
警告:与迭代(或尾递归优化)版本相比,递归代码一如既往地会受到堆栈溢出和内存使用量增加的影响,因此使用风险自负。
答案 2 :(得分:2)
从语法上讲,C ++代码与用C#编写的相同代码相同。不要让语言差异让你措手不及!它实际上看起来像C,因为变量是在函数的顶部声明的;这在C ++或C#中都不是绝对必要的。我更喜欢在第一次使用变量时声明变量,在单个语句中组合声明和初始化,但这只是一种风格偏好,不会改变代码的功能。
我会尝试通过在代码段的每一行添加注释来解释这一点:
// 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只是意味着函数在同一个函数中调用自身。这是有效的,因为n的阶乘等价于以下语句:
n! = n * (n-1)!
了解代码如何工作的一种伟大的方法是将其添加到测试项目中,然后使用调试器单步执行代码。 Visual Studio在C#应用程序中对此提供了非常丰富的支持。您可以观察函数如何递归调用自身,观察每一行按顺序执行,甚至看到变量的值随着对它们执行操作而改变。
答案 3 :(得分:1)
递归函数是一个在其体内调用自身的函数。因为它是有界的,并最终返回一个值,必须发生两件事:
它必须有一个基本情况,它不会再次调用自身,返回一个已知值。这个基本情况会停止递归。对于阶乘函数,当输入为0时,此值为1.
它的递归应用程序必须收敛到基本情况。对于阶乘,递归应用程序调用函数,输入减去1,最终会收敛到基本情况。
查看此函数的一种更简单的方法是这样(仅对正输入有效):
int factorial(int input) {
return input == 0 ? 1 : input * factorial(input - 1);
}
答案 4 :(得分:1)
递归函数是来自同一函数的函数调用
例如:
Test()
{
i++;
Test();
cout<<i;
}
查看它将一次又一次调用该函数的代码
递归问题它会无限地工作所以想要通过特定条件来阻止它
以上代码中的一些更改现在看起来
int i=0;
Test()
{
if(i==10) return;
i++;
Test();
cout<<i;
}
输出将打印10次,此处此行cout<<i;
将在返回后执行