2.7 beauty of programming-three solutions to the maximum common divisor [efficient method to solve gcd problem], beauty of Programming
[Link to this article]
Http://www.cnblogs.com/hellogiser/p/efficient-method-to-solve-gcd-problem.html
[Question]
Calculate the maximum Common Divisor (GCD) of two positive integers ). If both integers are large, is there any simple algorithm? For example, given two numbers 1 100 100 210 001,120 200 021, the maximum number of public approx is obtained.
[Solution]
[1. Division of Moving Phase]
Division: f (x, y) = f (y, x % y) (x> y)
F () = 6
[Code]
C ++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
/* Version: 1.0 Author: hellogiser Blog: http://www.cnblogs.com/hellogiser Date: 2014/7/8 */
Int gcd (int x, int y) { If (x <y) Return gcd (y, x ); If (y = 0) Return x; Else Return gcd (y, x % y ); } |
The modulo operation is used in this method. For large integers, the overhead of the modulo operation (Division) is very expensive and will become the bottleneck of the entire algorithm.
[2. Moving and subtraction]
Moving and subtraction: f (x, y) = f (y, x-y) (x> y)
F () = f (6) = 6
[Code]
C ++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
/* Version: 1.0 Author: hellogiser Blog: http://www.cnblogs.com/hellogiser Date: 2014/7/8 */
Int gcd (int x, int y) { If (x <y) Return gcd (y, x ); If (y = 0) Return x; Else Return gcd (y, x-y ); } |
This algorithm removes the hassle of division by large integers, but it also has shortcomings. The biggest bottleneck is that there are too many iterations. If such a situation occurs (1 000 000 000, 1), it is quite depressing.
[3. Parity method]
Parity method:
This method combines solution 1) and solution 2 to reduce the computing complexity and the number of iterations.
1: If both x and y are even, f (x, y) = 2 * f (x/2, y/2) = 2 * f (x> 1, y> 1)
2: If x is an even, and y is odd, f (x, y) = f (x/2, y) = f (x> 1, y)
3: If x is odd, y is even, f (x, y) = f (x, y/2) = f (x, y> 1)
4: If x and y are all odd, f (x, y) = f (y, x-y)
After f (x, y) = f (y, x-y), (x-y) is an even number, and the next step is divided by 2.
Therefore, in the worst case, the time complexity is O (log2 (max (x, y ))).
F (42, 30) = 2 * f (21, 15)
= 2 * f (15, 6)
= 2 * f (15, 3)
= 2 * f (3, 12) = 2 * f (12, 3)
= 2 * f (6, 3)
= 2 * f (3, 3)
= 2 * f (3, 0)
= 2*3
= 6
【Code]
C ++ Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
/* Version: 1.0 Author: hellogiser Blog: http://www.cnblogs.com/hellogiser Date: 2014/7/8 */
Bool IsEven (int x) { Return (x & 0x1) = 0; }
Int gcd (int x, int y) { If (x <y) Return gcd (y, x ); If (y = 0) Return x; Else { If (IsEven (x )) { If (IsEven (y) // case 1, x, y are even Return 2 * gcd (x> 1, y> 1 ); Else // case 2, x is even, y is odd Return gcd (x> 1, y ); } Else { If (IsEven (y) // case 3, x is odd, y is even Return gcd (x, y> 1 ); Else // case 4, x, y are all odd Return gcd (y, x-y ); } } } |
[Reference]
Http://blog.csdn.net/ajioy/article/details/7478008
Http://blog.csdn.net/rein07/article/details/6739688
[Link to this article]
Http://www.cnblogs.com/hellogiser/p/efficient-method-to-solve-gcd-problem.html