C # Recursive function detailed introduction and use method

Source: Internet
Author: User

What is a recursive function/method?
Either method can call itself or call itself, and when this method calls itself, we call it a recursive function or a recursive method.

there are usually two characteristics of recursion :
1. The recursive method will always call itself until certain conditions are met
2. The recursive method will have some parameters, and it will pass some new parameter values to itself.
What is a recursive function? There is no essential difference between functions and methods, but functions are used only within the class. Previously, there were only methods in C #, and anonymous functions started with. NET 3.5.

So, we'd better call the recursive method, not the recursive function, which is called recursion in this article.

Why recursion is used in the application? When to use recursion? How to use?
"Writing any program can be represented by an assignment and a if-then-else statement, while the while statement can be represented by assignment, If-then-else, and recursion." (from Ellis Horowitz, "Data structure Basics (C language edition)"-Fundamentals of Data Structure in C)
Recursive solutions are convenient and powerful for complex development, but the frequent use of call stacks can cause performance problems (sometimes very poor performance).

Call stack diagram
I'm going to introduce some examples to help you better understand the risks and rewards of recursion.
1. Factorial
Factorial (!) is the product of all positive integers that are less than a certain number.
0! = 1
1! = 1
2! = 2 * 1! = 2
3! = 3 * 2! = 6
...
N! = n * (n-1)!
The following is an implementation method for calculating the factorial (no recursion):


public long factorial (int n)
{
if (n = = 0)
return 1;
Long value = 1;
for (int i = n; i > 0; i--)
{
Value *= i;
}
return value;
}


The following is a recursive method for calculating factorial, which is more concise than the previous code.


public long factorial (int n)
{
if (n = = 0)//constraints, limit the method call itself
return 1;
return n * factorial (n-1);
}


You know, the factorial of n is actually the factorial of n-1 multiplied by N, and N>0.
It can be represented as factorial (n) = factorial (n-1) * n
This is the return value of the method, but we need a condition
If N=0 returns 1.
Now the logic of this program should be very clear, so that we can easily understand.

2. Fibonacci Series
The Fibonacci series are numbers arranged in the following order:
0,1,1,2,3,5,8,13,21,34,55,... If F0 = 0 and f1= 1 then Fn = Fn-1 + Fn-2
The following method is used to calculate the FN (no recursion, good performance)


public long Fib (int n)
{
if (n < 2)
return n;
Long[] f = new long[n+1];
F[0] = 0;
F[1] = 1;
for (int i = 2; I <= n; i++)
{
F[i] = F[i-1] + f[i-2];
}
return f[n];
}


If we use recursive methods, this code will be simpler, but the performance is poor.

Copy CodeThe code is as follows:
public long Fib (int n)
{
if (n = = 0 | | n = = 1)//Meet the conditions
return n;
return fib (k-2) + fib (k-1);
}
<strong><span style= "Font-size:medium" >3. Boolean Combo </SPAN></STRONG>


Sometimes the problem we need to solve is much more complex than the Fibonacci sequence, for example, we want to enumerate all the combinations of Boolean variables. In other words, if n=3, then we must output the following result:
True, True, true
True, True, False
True, False, True
True, False, False
False, True, true
False, True, False
False, False, True
False, False, False if n is large, and it is difficult to solve the problem without recursion.

Copy CodeThe code is as follows:
public void Compositionbooleans (string result, int counter)
{
if (counter = = 0)
Return
bool[] Booleans = new Bool[2] {true, false};
for (int j = 0; J < 2; J + +)
{
StringBuilder StringBuilder = new StringBuilder (result);
Stringbuilder.append (String. Format ("{0}", Booleans[j]. ToString ())). ToString ();
if (counter = = 1)
Console.WriteLine (Stringbuilder.tostring ());
Compositionbooleans (Stringbuilder.tostring (), counter-1);
}
}


Now let's call the above method :


Compositionboolean (String. Empty, 3);


Ian Shlasko recommends that we use recursion like this :


public void booleancompositions (int count)
{
Booleancompositions (Count-1, "true");
Booleancompositions (Count-1, "false");
}
private void booleancompositions (int counter, string partialoutput)
{
if (counter <= 0)
Console.WriteLine (Partialoutput);
Else
{
Booleancompositions (Counter-1, partialoutput+ ", true");
Booleancompositions (Counter-1, partialoutput+ ", false");
}
}


4. Get an inner exception
If you want to get innerexception, then choose the recursive method, it is very useful.


Public Exception getinnerexception (Exception ex)
{
Return (ex. InnerException = = null)? Ex:getinnerexception (ex. innerexception);
}


Why do you want to get the last innerexception?! This is not the subject of this article, our theme is that if you want to get the innermost innerexception, you can do it by recursive method.
Here's the code:


Return (ex. InnerException = = null)? Ex:getinnerexception (ex. innerexception);


equivalent to the following code


if (ex. InnerException = = null)//Limit conditions
return ex;
Return Getinnerexception (ex. innerexception);//Call yourself with an internal exception as a parameter


Now, once we get an exception, we can find the innermost innerexception. For example:

Try
{
throw new Exception ("This is the Exception",
New Exception ("This is the first inner Exception.",
New Exception ("The last inner Exception."));
}
catch (Exception ex)
{
Console.WriteLine (Getinnerexception (ex). Message);
}


I once wanted to write an article about anonymous recursion, but I found that my explanation couldn't go beyond that article.
5. Find Files

I used recursion in the demo project for you to download, and through this project you can search for a path and get the path to all the files in the current folder and its subfolders.


Private dictionary<string, string> errors = new dictionary<string, string> ();
Private list<string> result = new list<string> ();
private void Searchforfiles (string path)
{
Try
{
foreach (String fileName in Directory.GetFiles (path))//gets all files in the current path
{
Result. ADD (FileName);
}
foreach (String directory in Directory.getdirectories (path))//gets all folders in the current path
{
Searchforfiles (directory);//the methods calls itself with a new parameter, here!
}
}
catch (System.Exception ex)
{
Errors. ADD (Path, ex. Message);//stores Error Messages in a dictionary with path in key
}
}


This method does not seem to need to satisfy any conditions, because every directory without subdirectories will automatically traverse all child files.

Summary
We can actually replace recursion with recursion, and performance is better, but we may need more time overhead and non-recursive functions. But the point is that we have to choose the best implementation based on the scenario.

Dr. James Macaffrey thinks that recursion should be avoided, unless there is no way to do it. You can read his article.
I think :
A) If performance is very important, avoid using recursion
B) If the recursive method is not very complex, avoid using recursion
C) If both A and B are not satisfied, please do not hesitate to use recursion.
For example :
The first section (factorial): Recursion is not complicated here, so avoid recursion.
Section II (FIBONACCI): Recursive merging like this is not recommended.
Of course, I do not want to belittle the value of recursion, I remember the important chapter in artificial intelligence has a minimax algorithm (Minimax algorithm), all of which are implemented recursively.

C # Recursive function detailed introduction and use method

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.