Today, the great gods in my class are excited and looking for books on this algorithm looks like they have a lot of classic examples. The great gods are blank in programming, so I am confused when I see the recursion part. For example, I used the recursive algorithm in the book to explain the series of Fibonacci, which is quite concise and clear. The Code is as follows: unsigned long maid (int n)
{
If (n <= 2)
{
Return 1;
}
Else
{
Return maid (n-1) + maid (n-2 );
}
} I agree with the idea of recursion. The idea of simplification and isolation is like a lot of programming ideas, such as dynamic planning. However, I think most of the recursive ideas are simply simplified in terms of human acceptance. Actually, recursive algorithms are easy to understand, but they are not used. The above program is written clearly using the recurrence formula of the series. But as I said, this recursive algorithm actually wastes a lot of CPU resources. We can analyze it carefully, for example, f (5) = f (4) + f (3)
= F (3) + f (2) + f (2) + f (1)
= F (2) + f (1) + f (2) + f (2) + f (1)
= 1 + 1 + 1 + 1 + 1 here f (5) is calculated using 12 addition. In fact, we can find that after f (3) is calculated, f (4) in fact, you don't need to split it like I did. You just need to use the result of f (3). In other words, you can make full use of the sum of the first two items, there is a relationship between the two items, and it is not difficult to think that a non-recursive algorithm can be written as follows: unsigned long fibonacci (int n)
{
Unsigned long f0, f1, temp;
Int I;
If (n <= 2)
{
Return 1;
}
Else
{
For (f0 = f1 = 1, I = 3; I <= n; I ++)
{
Temp = f0 + f1;
F0 = f1;
F1 = temp;
}
Return f1;
}
} This algorithm uses a variable temp to save the sum of the two previous items, and then updates f0 and f1 in time. The return also returns temp, because my temp stores the same content as f1. Let's take a look at the number of additions we have made during the calculation of f (5). A careful number means that only three additions are used, greatly reducing the computing overhead, the recursive program above consumes a certain number of function call stacks because it is constantly calling functions. Why do you say that recursion is not used unless it is too complicated? The reason is one or two. I told my thoughts to Daniel in the class. He immediately told me a Faster Algorithm in a book, which shocked a group of grass in our class, he said so, by the above non recursive algorithm can be introduced in the calculation of f (n) at most not more than the N-2 addition, to speed up the program can only continue to reduce the addition, here is the essence of thinking. In fact, the method to reduce addition is to use multiplication. However, later I thought that multiplier is more complex than the adder, so we do not know the efficiency that can be improved, however, this idea is not general. In the linear algebra class, the teacher also introduced a pseudo-Fibonacci matrix, that is, a 2*2 matrix. The first line element is, and the second behavior is. We found that the value of f (n) is the sum of the two elements in the first row after the power of the matrix N-2, such as f (5) is equal to the power of the Matrix 3, in this case, the two elements in the first row are 3 and 2 respectively, so f (5) = 3 + 2. This is easy to push. If you calculate one or two, you will find this rule. Based on this idea, he wrote the following code: unsigned long fibonacci (int n)
{
Unsigned long a, B, c, d;
Int I;
If (n <= 2)
{
Return 1;
}
Else
{
Matrix_power (, N-2, & a, & B, & c, & d );
Return f1;
}
}
// Calculate the nth power of the matrix
Matrix_power (unsigned long a, unsigned long B, unsigned long c, unsigned long d, int n,
Unsigned long * aa, unsigned long * bb, unsigned long * cc, unsigned long * dd)
{
Unsigned long xa, xb, xc, xd;
If (1 = n)
{
* Aa = a, * bb = B, * cc = c, * dd = d;
}
Else if (n & 0x01 = 1)
{
Matrix_power (a, B, c, d, n-1, & xa, & xb, * xc, * xd );
* Aa = a * xa + B * xc;
* Bb = a * xb + B * xd;
* Cc = c * xa + d * xc;
* Dd = c * xb + d * xd;
}
Else
{
Matrix_power (a, B, c, d, n> 1, & xa, & xb, & xc, & xd );
* Aa = xa * xa + xb * xc;
* Bb = xa * xb + xb * xd;
* Cc = xc * xa + xd * xc;
* Dd = xc * xb + xd * xd;
}
} We can also find that this Code uses a sub-governance idea to evaluate the n parity when the n power of the matrix is obtained. If it is an even number, it recursively calculates the n/2 power and then squares, if it is an odd number, it is written as the even power of M * M. recursion is used here! I didn't want to do recursion to go around such a large circle. Now I am back to the origin. I am so sorry to go to Daniel. I have to do it myself. Isn't it just the power of a matrix? I don't need recursion either. It is too complicated to get the matrix together. I suppose I want to calculate the N power of a number m! If we use a recursive algorithm to calculate the n power of m, and then list the n value passed in for each recursive call, I find that n is a multiple of 2 for each call, at this time, I seem to have seen something, so I carefully studied it and added a bold conjecture, finally let me find a rule, to calculate the power of n in m, we can write n as a binary number, find the bit whose binary bit is 1, and then write n as the sum of the weights corresponding to these bits of 2, so the Npower of m can be written into the sum of these weights of m. For example, to calculate the 9 power of m, write 9 as the binary number of 1001, so the power of 9 = 2 is 0 + the power of 2, so that a = 2 is 0, and B = 2 is 3, then the 9 power of m = the power of m + the B power of m. In this way, I only need to traverse the binary bits of n, so I quickly modified the above Code to calculate the n of the matrix: // change the value of the output parameter.
GetTemp (unsigned long ** aa, unsigned long ** bb, unsigned long ** cc, unsigned long ** dd,
Unsigned long a, unsigned long B, unsigned long c, unsigned long d)
{
Unsigned long tempa = ** aa, tempb = ** bb, tempc = ** cc, tempd = ** dd;
Tempa = ** aa * a + (** bb) * c;
Tempb = ** aa * B + (** bb) * d;
Tempc = ** cc * a + (** dd) * c;
Tempd = ** cc * B + (** dd) ** d;
** Aa = tempa;
** Bb = tempb;
** Cc = tempc;
** Dd = tempd;
} // The n correction version of the computing matrix
Matrix_power (unsigned long a, unsigned long B, unsigned long c, unsigned long d, int n,
Unsigned long * aa, unsigned long * bb, unsigned long * cc, unsigned long * dd)
{
Unsigned long xa = a, xb = B, xc = c, xd = d;
Unsigned long tempa = a, tempb = B, tempc = c, tempd = d;
Int flageven = 0, flag = 1;
If (! (N & 0x01UL ))
{
Flageven = 1;
}
While (n> 0)
{
If (1 = (n & 0x01UL ))
{
If (1 = flag)
{
* Aa =;
* Bb = B;
* Cc = c;
* Dd = d;
Flag = 0;
If (1 = flageven)
{
GetTemp (& aa, & bb, & cc, & dd, xa, xb, xc, xd );
}
}
Else
{
GetTemp (& aa, & bb, & cc, & dd, xa, xb, xc, xd );
}
}
Tempa = xa * a + xb * c;
Tempb = xa * B + xb * d;
Tempc = xc * a + xd * c;
Tempd = xc * B + xd * d;
Xa = tempa;
Xb = tempb;
Xc = tempc;
Xd = tempd;
N> = 1;
}
} After half a night of busy work, the fight against recursion finally ended. So far, this Fibonacci series has been gradually won, and a non-recursive algorithm that I think is acceptable has been released. There are still a lot to discuss about recursion, but it's already morning. I 'd like to take a break and share my experience with you later. At the same time, I hope you can make any suggestions or questions about the algorithms above. We will discuss the most convenient communication on the Internet. I look forward to your attention.
This article from the "cainiao surfaced" blog, please be sure to keep this source http://rangercyh.blog.51cto.com/1444712/292806