Stein算法或二进制GCD算法是一种计算两个非负整数的最大公约数的算法。斯坦因的算法用算术移位,比较和减法代替除法。
例子:
Input: a = 17, b = 34
Output : 17
Input: a = 50, b = 49
Output: 1
使用斯坦因算法gcd(a,b)查找GCD的算法
- 如果a和b均为0,则gcd为零gcd(0,0)= 0。
- gcd(a,0)= a和gcd(0,b)= b,因为一切都除以0。
- 如果a和b均为偶数,则gcd(a,b)= 2 * gcd(a / 2,b / 2),因为2是一个公因数。 2的乘法可以通过按位移位运算运算符。
- 如果a是偶数而b是奇数,则gcd(a,b)= gcd(a / 2,b)。同样,如果a为奇数,b为偶数,则
gcd(a,b)= gcd(a,b / 2)。这是因为2不是一个常见的除数。 - 如果a和b都为奇数,则gcd(a,b)= gcd(| ab | / 2,b)。请注意,两个奇数之差为偶数
- 重复步骤3-5,直到a = b或直到a =0。在两种情况下,GCD都是power(2,k)* b,其中power(2,k)为2会提高到k的幂。在步骤2中找到的2的公因数。
迭代实现
C++
// Iterative C++ program to
// implement Stein's Algorithm
#include
using namespace std;
// Function to implement
// Stein's Algorithm
int gcd(int a, int b)
{
/* GCD(0, b) == b; GCD(a, 0) == a,
GCD(0, 0) == 0 */
if (a == 0)
return b;
if (b == 0)
return a;
/*Finding K, where K is the
greatest power of 2
that divides both a and b. */
int k;
for (k = 0; ((a | b) & 1) == 0; ++k)
{
a >>= 1;
b >>= 1;
}
/* Dividing a by 2 until a becomes odd */
while ((a & 1) == 0)
a >>= 1;
/* From here on, 'a' is always odd. */
do
{
/* If b is even, remove all factor of 2 in b */
while ((b & 1) == 0)
b >>= 1;
/* Now a and b are both odd.
Swap if necessary so a <= b,
then set b = b - a (which is even).*/
if (a > b)
swap(a, b); // Swap u and v.
b = (b - a);
}while (b != 0);
/* restore common factors of 2 */
return a << k;
}
// Driver code
int main()
{
int a = 34, b = 17;
printf("Gcd of given numbers is %d\n", gcd(a, b));
return 0;
}
Java
// Iterative Java program to
// implement Stein's Algorithm
import java.io.*;
class GFG {
// Function to implement Stein's
// Algorithm
static int gcd(int a, int b)
{
// GCD(0, b) == b; GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// Finding K, where K is the greatest
// power of 2 that divides both a and b
int k;
for (k = 0; ((a | b) & 1) == 0; ++k)
{
a >>= 1;
b >>= 1;
}
// Dividing a by 2 until a becomes odd
while ((a & 1) == 0)
a >>= 1;
// From here on, 'a' is always odd.
do
{
// If b is even, remove
// all factor of 2 in b
while ((b & 1) == 0)
b >>= 1;
// Now a and b are both odd. Swap
// if necessary so a <= b, then set
// b = b - a (which is even)
if (a > b)
{
// Swap u and v.
int temp = a;
a = b;
b = temp;
}
b = (b - a);
} while (b != 0);
// restore common factors of 2
return a << k;
}
// Driver code
public static void main(String args[])
{
int a = 34, b = 17;
System.out.println("Gcd of given "
+ "numbers is " + gcd(a, b));
}
}
// This code is contributed by Nikita Tiwari
Python
# Iterative Python 3 program to
# implement Stein's Algorithm
# Function to implement
# Stein's Algorithm
def gcd(a, b):
# GCD(0, b) == b; GCD(a, 0) == a,
# GCD(0, 0) == 0
if (a == 0):
return b
if (b == 0):
return a
# Finding K, where K is the
# greatest power of 2 that
# divides both a and b.
k = 0
while(((a | b) & 1) == 0):
a = a >> 1
b = b >> 1
k = k + 1
# Dividing a by 2 until a becomes odd
while ((a & 1) == 0):
a = a >> 1
# From here on, 'a' is always odd.
while(b != 0):
# If b is even, remove all
# factor of 2 in b
while ((b & 1) == 0):
b = b >> 1
# Now a and b are both odd. Swap if
# necessary so a <= b, then set
# b = b - a (which is even).
if (a > b):
# Swap u and v.
temp = a
a = b
b = temp
b = (b - a)
# restore common factors of 2
return (a << k)
# Driver code
a = 34
b = 17
print("Gcd of given numbers is ", gcd(a, b))
# This code is contributed by Nikita Tiwari.
C#
// Iterative C# program to implement
// Stein's Algorithm
using System;
class GFG {
// Function to implement Stein's
// Algorithm
static int gcd(int a, int b)
{
// GCD(0, b) == b; GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// Finding K, where K is the greatest
// power of 2 that divides both a and b
int k;
for (k = 0; ((a | b) & 1) == 0; ++k)
{
a >>= 1;
b >>= 1;
}
// Dividing a by 2 until a becomes odd
while ((a & 1) == 0)
a >>= 1;
// From here on, 'a' is always odd
do
{
// If b is even, remove
// all factor of 2 in b
while ((b & 1) == 0)
b >>= 1;
/* Now a and b are both odd. Swap
if necessary so a <= b, then set
b = b - a (which is even).*/
if (a > b) {
// Swap u and v.
int temp = a;
a = b;
b = temp;
}
b = (b - a);
} while (b != 0);
/* restore common factors of 2 */
return a << k;
}
// Driver code
public static void Main()
{
int a = 34, b = 17;
Console.Write("Gcd of given "
+ "numbers is " + gcd(a, b));
}
}
// This code is contributed by nitin mittal
PHP
>= 1;
$b >>= 1;
}
// Dividing a by 2 until a becomes odd
while (($a & 1) == 0)
$a >>= 1;
// From here on, 'a' is always odd.
do
{
// If b is even, remove
// all factor of 2 in b
while (($b & 1) == 0)
$b >>= 1;
// Now a and b are both odd. Swap
// if necessary so a <= b, then set
// b = b - a (which is even)
if ($a > $b)
swap($a, $b); // Swap u and v.
$b = ($b - $a);
} while ($b != 0);
// restore common factors of 2
return $a << $k;
}
// Driver code
$a = 34; $b = 17;
echo "Gcd of given numbers is " .
gcd($a, $b);
// This code is contributed by ajit
?>
Javascript
C++
// Recursive C++ program to
// implement Stein's Algorithm
#include
using namespace std;
// Function to implement
// Stein's Algorithm
int gcd(int a, int b)
{
if (a == b)
return a;
// GCD(0, b) == b; GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// look for factors of 2
if (~a & 1) // a is even
{
if (b & 1) // b is odd
return gcd(a >> 1, b);
else // both a and b are even
return gcd(a >> 1, b >> 1) << 1;
}
if (~b & 1) // a is odd, b is even
return gcd(a, b >> 1);
// reduce larger number
if (a > b)
return gcd((a - b) >> 1, b);
return gcd((b - a) >> 1, a);
}
// Driver code
int main()
{
int a = 34, b = 17;
printf("Gcd of given numbers is %d\n", gcd(a, b));
return 0;
}
Java
// Recursive Java program to
// implement Stein's Algorithm
import java.io.*;
class GFG {
// Function to implement
// Stein's Algorithm
static int gcd(int a, int b)
{
if (a == b)
return a;
// GCD(0, b) == b; GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// look for factors of 2
if ((~a & 1) == 1) // a is even
{
if ((b & 1) == 1) // b is odd
return gcd(a >> 1, b);
else // both a and b are even
return gcd(a >> 1, b >> 1) << 1;
}
// a is odd, b is even
if ((~b & 1) == 1)
return gcd(a, b >> 1);
// reduce larger number
if (a > b)
return gcd((a - b) >> 1, b);
return gcd((b - a) >> 1, a);
}
// Driver code
public static void main(String args[])
{
int a = 34, b = 17;
System.out.println("Gcd of given"
+ "numbers is " + gcd(a, b));
}
}
// This code is contributed by Nikita Tiwari
Python
# Recursive Python 3 program to
# implement Stein's Algorithm
# Function to implement
# Stein's Algorithm
def gcd(a, b):
if (a == b):
return a
# GCD(0, b) == b; GCD(a, 0) == a,
# GCD(0, 0) == 0
if (a == 0):
return b
if (b == 0):
return a
# look for factors of 2
# a is even
if ((~a & 1) == 1):
# b is odd
if ((b & 1) == 1):
return gcd(a >> 1, b)
else:
# both a and b are even
return (gcd(a >> 1, b >> 1) << 1)
# a is odd, b is even
if ((~b & 1) == 1):
return gcd(a, b >> 1)
# reduce larger number
if (a > b):
return gcd((a - b) >> 1, b)
return gcd((b - a) >> 1, a)
# Driver code
a, b = 34, 17
print("Gcd of given numbers is ",
gcd(a, b))
# This code is contributed
# by Nikita Tiwari.
C#
// Recursive C# program to
// implement Stein's Algorithm
using System;
class GFG {
// Function to implement
// Stein's Algorithm
static int gcd(int a, int b)
{
if (a == b)
return a;
// GCD(0, b) == b;
// GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// look for factors of 2
// a is even
if ((~a & 1) == 1) {
// b is odd
if ((b & 1) == 1)
return gcd(a >> 1, b);
else
// both a and b are even
return gcd(a >> 1, b >> 1) << 1;
}
// a is odd, b is even
if ((~b & 1) == 1)
return gcd(a, b >> 1);
// reduce larger number
if (a > b)
return gcd((a - b) >> 1, b);
return gcd((b - a) >> 1, a);
}
// Driver code
public static void Main()
{
int a = 34, b = 17;
Console.Write("Gcd of given"
+ "numbers is " + gcd(a, b));
}
}
// This code is contributed by nitin mittal.
PHP
> 1, $b);
else // both a and b are even
return gcd($a >> 1, $b >> 1) << 1;
}
if (~$b & 1) // a is odd, b is even
return gcd($a, $b >> 1);
// reduce larger number
if ($a > $b)
return gcd(($a - $b) >> 1, $b);
return gcd(($b - $a) >> 1, $a);
}
// Driver code
$a = 34; $b = 17;
echo "Gcd of given numbers is: ",
gcd($a, $b);
// This code is contributed by aj_36
?>
Javascript
输出
Gcd of given numbers is 17
递归实施
C++
// Recursive C++ program to
// implement Stein's Algorithm
#include
using namespace std;
// Function to implement
// Stein's Algorithm
int gcd(int a, int b)
{
if (a == b)
return a;
// GCD(0, b) == b; GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// look for factors of 2
if (~a & 1) // a is even
{
if (b & 1) // b is odd
return gcd(a >> 1, b);
else // both a and b are even
return gcd(a >> 1, b >> 1) << 1;
}
if (~b & 1) // a is odd, b is even
return gcd(a, b >> 1);
// reduce larger number
if (a > b)
return gcd((a - b) >> 1, b);
return gcd((b - a) >> 1, a);
}
// Driver code
int main()
{
int a = 34, b = 17;
printf("Gcd of given numbers is %d\n", gcd(a, b));
return 0;
}
Java
// Recursive Java program to
// implement Stein's Algorithm
import java.io.*;
class GFG {
// Function to implement
// Stein's Algorithm
static int gcd(int a, int b)
{
if (a == b)
return a;
// GCD(0, b) == b; GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// look for factors of 2
if ((~a & 1) == 1) // a is even
{
if ((b & 1) == 1) // b is odd
return gcd(a >> 1, b);
else // both a and b are even
return gcd(a >> 1, b >> 1) << 1;
}
// a is odd, b is even
if ((~b & 1) == 1)
return gcd(a, b >> 1);
// reduce larger number
if (a > b)
return gcd((a - b) >> 1, b);
return gcd((b - a) >> 1, a);
}
// Driver code
public static void main(String args[])
{
int a = 34, b = 17;
System.out.println("Gcd of given"
+ "numbers is " + gcd(a, b));
}
}
// This code is contributed by Nikita Tiwari
Python
# Recursive Python 3 program to
# implement Stein's Algorithm
# Function to implement
# Stein's Algorithm
def gcd(a, b):
if (a == b):
return a
# GCD(0, b) == b; GCD(a, 0) == a,
# GCD(0, 0) == 0
if (a == 0):
return b
if (b == 0):
return a
# look for factors of 2
# a is even
if ((~a & 1) == 1):
# b is odd
if ((b & 1) == 1):
return gcd(a >> 1, b)
else:
# both a and b are even
return (gcd(a >> 1, b >> 1) << 1)
# a is odd, b is even
if ((~b & 1) == 1):
return gcd(a, b >> 1)
# reduce larger number
if (a > b):
return gcd((a - b) >> 1, b)
return gcd((b - a) >> 1, a)
# Driver code
a, b = 34, 17
print("Gcd of given numbers is ",
gcd(a, b))
# This code is contributed
# by Nikita Tiwari.
C#
// Recursive C# program to
// implement Stein's Algorithm
using System;
class GFG {
// Function to implement
// Stein's Algorithm
static int gcd(int a, int b)
{
if (a == b)
return a;
// GCD(0, b) == b;
// GCD(a, 0) == a,
// GCD(0, 0) == 0
if (a == 0)
return b;
if (b == 0)
return a;
// look for factors of 2
// a is even
if ((~a & 1) == 1) {
// b is odd
if ((b & 1) == 1)
return gcd(a >> 1, b);
else
// both a and b are even
return gcd(a >> 1, b >> 1) << 1;
}
// a is odd, b is even
if ((~b & 1) == 1)
return gcd(a, b >> 1);
// reduce larger number
if (a > b)
return gcd((a - b) >> 1, b);
return gcd((b - a) >> 1, a);
}
// Driver code
public static void Main()
{
int a = 34, b = 17;
Console.Write("Gcd of given"
+ "numbers is " + gcd(a, b));
}
}
// This code is contributed by nitin mittal.
的PHP
> 1, $b);
else // both a and b are even
return gcd($a >> 1, $b >> 1) << 1;
}
if (~$b & 1) // a is odd, b is even
return gcd($a, $b >> 1);
// reduce larger number
if ($a > $b)
return gcd(($a - $b) >> 1, $b);
return gcd(($b - $a) >> 1, $a);
}
// Driver code
$a = 34; $b = 17;
echo "Gcd of given numbers is: ",
gcd($a, $b);
// This code is contributed by aj_36
?>
Java脚本
输出
Gcd of given numbers is 17
时间复杂度:O(N * N),其中N是较大数字中的位数。
您可能还会喜欢–基本和扩展欧几里得算法
参考文献:
- https://zh.wikipedia.org/wiki/Binary_GCD_algorithm
- http://andreinc.net/2010/12/12/binary-gcd-steins-algorithm-in-c/
- http://www.cse.unt.edu/~tarau/teaching/PP/NumberTheoretical/GCD/Binary%20GCD%20algorithm.pdf