Recursive algorithm (1)
There are so many things going on recently that there is very little time to be completely quiet about something, and whenever you focus on writing code, you are always interrupted by something else. Okay, Sunday's coming, and finally we can spare some time. J
The first chapter of code Beauty has a question about pattern matching, which is to find the matching value in the corresponding text according to the regular expression, find the return 1, not found return 0. Despite the concrete implementation, the graceful recursive invocation in the inside attracted me deeply. So, I began to rethink recursion, after all, some of the details before the thinking is not in place.
What is recursion
My impression of recursion is that the function calls itself to complete a pre-defined operation. Of course, the actual content involved is more, such as the conditions of exit recursion, code logic, parameters and so on.
Recursion can be understood as a stack, that is, the call sequence is stored in the stack in the form of sequential structures and in the order of LIFO. For example, by adding the presence of such a call to A ()->b ()->c ()->d (), then its order in the stack is as follows,
A (): int |
B (): int |
C (): int |
D (): int |
It is not difficult to see through this example that all of the names of B,c,d are replaced by a, which is the entire process of recursive invocation of a.
Let's look at a concrete example of how to calculate the and of 1 to n natural integers.
{1, 2, 3, 5, ..., n}
Solution One
Defines a global variable that is used to store the current and.
The specific implementation is as follows
intsum =0; Private voidGetsum (intN) {if(n = =0)return; if(N <0) Throw NewArgumentException ("Invalid input."); Sum+=N; Getsum (n-1); }
There is no problem with this recursive logic, but a variable is defined, and as a final user, it needs to be encapsulated on top of the other layer to be used. Of course, you can also write a function to re-encapsulate, and then expose this wrap version.
So is there a better solution?
Solution Two
Defines a function that has a return value.
At the outset, I introduce recursion similar to the stack, so recursive invocation also follows the principle of post-invocation. If you add the return value, then you only need to calculate the current n value of all values before N and that is, you can get the number of N. For example there are 10 numbers, the current n is 5, then this layer recursion is 5 and.
Let's take a look at the code and then do the specific analysis.
Private intGetsumwithreturn (intN) {if(N <0) { Throw NewArgumentException ("Invalid input."); } if(n = =0) return 0; returnn + getsumwithreturn (n-1); }
Analytical Solution Two
- When n is less than 0, it is considered an illegal operation.
- When n equals 0 is assumed to have been calculated to the minimum, the recursion can be exited at this time.
- Returns the value of the current n before n-1
Take n equals 5 For example, the structure of the stack is as follows, notice, from the bottom of the watch and pay attention to the highlighted part. (Because the stack of the order is reversed, from the bottom of the view, below the top of the stack)
Function Call |
Function Body |
Getsumwithreturn (5) |
private int Getsumwithreturn (int n)//n = 5 { if (n < 0) { throw new ArgumentException ("Invalid input."); } if (n = = 0) return 0; return n + getsumwithreturn (n-1);//5 + ten = 15, return } |
Getsumwithreturn (4) |
private int Getsumwithreturn (int n)//n = 4 { if (n < 0) { throw new ArgumentException ("Invalid input."); } if (n = = 0) return 0; return n + getsumwithreturn (n-1);//4 + 6 = ten, return 10 } |
Getsumwithreturn (3) |
private int Getsumwithreturn (int n)//n = 3 { if (n < 0) { throw new ArgumentException ("Invalid input."); } if (n = = 0) return 0; return n + getsumwithreturn (n-1);//3 + 3 = 6, return 6 } |
Getsumwithreturn (2) |
private int Getsumwithreturn (int n)//n = 2 { if (n < 0) { throw new ArgumentException ("Invalid input."); } if (n = = 0) return 0; return n + getsumwithreturn (n-1);//2 + 1 = 3, return 3 } |
Getsumwithreturn (1) |
private int Getsumwithreturn (int n)//n = 1 { if (n < 0) { throw new ArgumentException ("Invalid input."); } if (n = = 0) return 0; return n + getsumwithreturn (n-1);//1 + 0 = 1, return 1 } |
Getsumwithreturn (0) |
private int Getsumwithreturn (int n)//n = 0 { if (n < 0) { throw new ArgumentException ("Invalid input."); } if (n = = 0)//n = 0, then return 0. return 0; return n + getsumwithreturn (n-1); } |
[Original] algorithm recursion (1)