📜  斯坦因发现GCD的算法

📅  最后修改于: 2021-04-23 15:58:54             🧑  作者: Mango

Stein算法二进制GCD算法是一种计算两个非负整数的最大公约数的算法。斯坦因的算法用算术移位,比较和减法代替除法。

例子:

Input: a = 17, b = 34 
Output : 17

Input: a = 50, b = 49
Output: 1

使用斯坦因算法gcd(a,b)查找GCD的算法

  1. 如果a和b均为0,则gcd为零gcd(0,0)= 0。
  2. gcd(a,0)= a和gcd(0,b)= b,因为一切都除以0。
  3. 如果a和b均为偶数,则gcd(a,b)= 2 * gcd(a / 2,b / 2),因为2是一个公因数。 2的乘法可以通过按位移位运算运算符。
  4. 如果a是偶数而b是奇数,则gcd(a,b)= gcd(a / 2,b)。同样,如果a为奇数,b为偶数,则
    gcd(a,b)= gcd(a,b / 2)。这是因为2不是一个常见的除数。
  5. 如果a和b都为奇数,则gcd(a,b)= gcd(| ab | / 2,b)。请注意,两个奇数之差为偶数
  6. 重复步骤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