问题
I'm trying to understand what exactly is recursion and have not been able to find an answer to the following.
My current understanding of recursion is that it is anytime a method calls itself.
I.E
Menu()
{
if(i<2)
{Console.WriteLine();}
else
{Menu();}
}
The above is an example of recursion a method calling itself.
What I'm not sure about is a scenario like:
Menu()
{
if(i<2)
{Console.WriteLine();}
else
{Console.WriteLine("Something Went Wrong!"); MenuError();}
}
MenuError()
{
Console.WriteLine("Something went wrong!");
Menu();
}
If the method calls a method which then calls it is this still recursion ?
回答1:
My current understanding of recursion is that it is anytime a method calls itself.
That is correct. Recursive definitions are self-referencing definitions.
Two interesting properties of recursive definitions are productivity and termination. A program is productive if it continues to yields output, though the full output may never come (hence it may not terminate). A program terminates if it yields its full output in finite time.
For example, this is a productive, non-terminating program:
Naturals(int i) {
Console.WriteLine(i);
Naturals(i + 1);
}
This is a terminating program:
UpToTen(int i) {
Console.WriteLine(i);
if (i < 10) UpToTen(i + 1);
}
This is a non-productive program:
DoNothing() {
DoNothing();
}
If Menu
calls MenuError
, and MenuError
calls Menu
, this is sometimes called mutual recursion. The only difference is our organisation; we can rewrite the code to just have one method by inlining MenuError
.
Menu() {
if (i < 2) {
Console.WriteLine();
}
else {
Console.WriteLine("Something Went Wrong!");
Console.WriteLine("Something went wrong!");
Menu();
}
}
You can in fact abstract recursion itself:
// General definition
A Fix<A>(Func<Func<A>,A> f) {
return f(() => Fix(f));
}
// Special definition for void functions
void Fix(Action<Action> f) {
f(() => Fix(f));
}
void Menu(Action menu) {
if (i < 2) {
Console.WriteLine();
}
else {
Console.WriteLine("Something Went Wrong!");
Console.WriteLine("Something went wrong!");
menu();
}
}
Fix(Menu);
Here is another example using Fix
to define the factorial function.
Func<int, int> Fac(Func<Func<int, int>> fac) {
return i => i == 0 ? 1 : i * fac()(i - 1);
}
// Fix<Func<int, int>>(Fac) is the factorial function
You may wonder why Fix
does not have the signature A Fix<A>(Func<A,A> f)
instead. This is because C# is a strict language, meaning it evaluates arguments before it evaluates function application. With the simpler signature the C# program would end up in infinite recursion.
回答2:
Yes it is still recursion. There are different types of recursion like Tail recursion, Tree Recursion etc. You can check out google for rest.
By the way, in the second case, if value of i is greater than or equal to 2, you will get stack overflow error as each one will call another one.
来源:https://stackoverflow.com/questions/38278491/what-is-and-is-not-recursion