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