logo

Algorytm Steina do znajdowania GCD

Wypróbuj w praktyce GfG ' title=

Algorytm Steina Lub binarny algorytm GCD to algorytm obliczający największy wspólny dzielnik dwóch nieujemnych liczb całkowitych. Algorytm Steina zastępuje dzielenie porównaniami przesunięć arytmetycznych i odejmowaniem.

Przykłady:  



Wejście : a = 17 b = 34
Wyjście : 17

Wejście : a = 50 b = 49
Wyjście : 1

Algorytm znajdowania GCD przy użyciu algorytmu Steina gcd(a b)  

Algorytm jest głównie optymalizacją w stosunku do standardu Algorytm Euklidesa dla NWD



  1. Jeśli oba a i b wynoszą 0, gcd wynosi zero, gcd(0 0) = 0.
  2. gcd(a 0) = a i gcd(0 b) = b, ponieważ wszystko dzieli 0.
  3. Jeśli a i b są parzyste gcd(a b) = 2*gcd(a/2 b/2), ponieważ 2 jest wspólnym dzielnikiem. Mnożenie przez 2 można wykonać za pomocą operatora przesunięcia bitowego.
  4. Jeśli a jest parzyste, a b jest nieparzyste gcd(a b) = gcd(a/2 b). Podobnie, jeśli a jest nieparzyste, a b jest parzyste 
    gcd(a b) = gcd(a b/2). Dzieje się tak dlatego, że 2 nie jest wspólnym dzielnikiem.
  5. Jeśli oba a i b są nieparzyste, to gcd(a b) = gcd(|a-b|/2 b). Zauważ, że różnica dwóch liczb nieparzystych jest parzysta
  6. Powtarzaj kroki 3–5, aż a = b lub a = 0. W obu przypadkach GCD to potęga (2 k) * b, gdzie moc (2 k) wynosi 2, podnieś do potęgi k, a k jest liczbą wspólnych czynników 2 znalezionych w kroku 3.
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 %dn' 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 
JavaScript
<script> // Iterative JavaScript program to // implement Stein's Algorithm // Function to implement // Stein's Algorithm function 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. */  let 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){  let t = a;  a = b;  b = t;  }  b = (b - a);  }while (b != 0);  /* restore common factors of 2 */  return a << k; } // Driver code  let a = 34 b = 17;  document.write('Gcd of given numbers is '+ gcd(a b)); // This code contributed by gauravrajput1  </script> 
PHP
 // Iterative php program to  // implement Stein's Algorithm // Function to implement  // Stein's Algorithm function 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; 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 $a = 34; $b = 17; echo 'Gcd of given numbers is ' . gcd($a $b); // This code is contributed by ajit ?> 

Wyjście
Gcd of given numbers is 17

Złożoność czasowa: O(N*N)
Przestrzeń pomocnicza: O(1)

[Oczekiwane podejście 2] Implementacja rekurencyjna - O(N*N) Czas i O(N*N) Przestrzeń

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 %dn' 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. 
JavaScript
<script> // JavaScript program to // implement Stein's Algorithm  // Function to implement  // Stein's Algorithm  function 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  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  let a = 34 b = 17;  document.write('Gcd of given '  + 'numbers is ' + gcd(a b));   </script> 
PHP
 // Recursive PHP program to // implement Stein's Algorithm // Function to implement // Stein's Algorithm function 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 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 $a = 34; $b = 17; echo 'Gcd of given numbers is: ' gcd($a $b); // This code is contributed by aj_36 ?> 

Wyjście
Gcd of given numbers is 17

Złożoność czasu : O(N*N) gdzie N jest liczbą bitów w większej liczbie.
Przestrzeń pomocnicza: O(N*N) gdzie N jest liczbą bitów w większej liczbie.

Może ci się również spodobać - Podstawowy i rozszerzony algorytm euklidesowy

Zalety w porównaniu z algorytmem GCD Euclida

  • Algorytm Steina jest zoptymalizowaną wersją algorytmu GCD Euclida.
  • jest to bardziej wydajne przy użyciu operatora przesunięcia bitowego.