Реализации алгоритмов/Бинарный алгоритм вычисления НОД: различия между версиями
Содержимое удалено Содержимое добавлено
Улучшена разметка, оптимизирован код |
|||
Строка 1:
{{wikipedia |Бинарный алгоритм вычисления НОД}}
==[[w:C (язык программирования)|С]]==
Без рекурсии:
<source lang="c">
typedef unsigned int IntType; /* Вместо unsigned int можно подставить любой другой целочисленный тип */
IntType gcd (IntType a, IntType b) {
int shift;
return
/* Вычисление shift = lg K, где K — наибольшая степень 2, на которую делятся без остатка a и b. */
for (shift = 0;
/*
do {
while ((
/*
if (
} else {
}
} while (
return
}
</source>
==
Рекурсия:
<source lang="csharp">
long GCD (long a, long b)
{
if (a == 0)
return b; // НОД(0, b) = b
if (
return a; // НОД(a, 0) = a
if
if
return
if (a & 1 == 0) // Если а — чётное, то…
return (b & 1 == 0)
? GCD(a >> 1, b >> 1) << 1 // …если b — чётное, то НОД(a, b) = 2 * НОД(a / 2, b / 2)
: GCD(a >> 1, b); // …если b — нечётное, то НОД(a, b) = НОД(a / 2, b)
else // Если a — нечётное, то…
return (b & 1 == 0)
? GCD(a, b >> 1) // …если b — чётное, то НОД(a, b) = НОД(a, b / 2)
: GCD(b, (long)Math.Abs(a - b)); // …если b — нечётное, то НОД(a, b) = НОД(b, |a - b|)
}
</source>
==[[w:JavaScript|JavaScript]]==
Без рекурсии:
<source lang="javascript">
function GCD (a, b) { // НОД двух целых чисел
var factor = 1;
while (true) {
// НОД(0, b) = b; НОД(a, 0) = a; НОД(a, a) = a;
if (a == b)
if (a == 0)
throw 'GCD(0, 0)'
else
return factor * a;
if (a == 0)
return factor * b;
if (b == 0)
return factor * a;
// НОД(1, b) = 1; НОД(a, 1) = 1;
if (a == 1 || b == 1)
return factor;
//Если a и b чётные, то НОД(a, b) = 2 * НОД(a / 2, b / 2);
if (!(a & 1) && !(b & 1)){
factor <<= 1;
a >>= 1;
b >>= 1;
}
// Если a чётное, b нечётное, то НОД(a, b) = НОД(a / 2, b);
else if (!(a & 1))
a >>= 1;
// Если b чётное, a нечётное, то НОД(a, b) = НОД(a, b / 2);
else if (!(b & 1))
b >>= 1;
// Если a и b нечётные и b > a, то НОД(a, b) = НОД((b - a) / 2, a);
else if (b > a)
b = (b - a) >> 1;
// Если a и b нечётные и b < a, то НОД(a, b) = НОД((a - b) / 2, b);
else
a = (a - b) >> 1;
}
}
</source>
==[[w:Паскаль (язык программирования)|Pascal]]==
Рекурсия:
<source lang="pascal">
type IntType = Integer; { Вместо Integer можно подставить любой другой целочисленный тип }
function GCD (a, b: IntType): IntType;
begin
if a = 0 then
GCD := b { НОД(0, b) = b }
else if b = 0 then
GCD := a { НОД(a, 0) = a }
else if a = b then
GCD := a { НОД(a, a) = a }
else if (a = 1) or (b = 1) then
GCD := 1 { НОД(1, b) = НОД(a, 1) = 1 }
else if Odd(a) then { Если а — нечётное, то… }
if Odd(b) then { …если b — нечётное, то… }
GCD := GCD(b, Abs(a
else { …если b — чётное, то… }
GCD := GCD(a, b shr 1) { НОД(a, b) = НОД(a, b / 2) }
else { Если a — чётное… }
if Odd(b) then { …если b — нечётное, то… }
GCD := GCD(a shr 1, b)
else { …если b — чётное, то… }
GCD := GCD(a shr 1, b shr 1) shl 1 { НОД(a,
end;
</source>
==
Без рекурсии:
<source lang="perl">
sub
{
return $_[0] if $_[1] == 0;
Строка 147 ⟶ 166 :
</source>
==
<!-- Добавил Рыжий Лис red-fox0@mail.ru -->
Рекурсия:
<source lang="scala">
if (a == 0) return b;
if (b == 0) return a;
if (a == b) return a;
if (a == 1 || b == 1) return 1;
if ((a % 2 == 0) && (b % 2 == 0)) return 2 * GCD(a / 2, b / 2);
if ((a % 2 == 0) && (b % 2 != 0)) return GCD(a / 2, b);
if ((a % 2 != 0) && (b % 2 == 0)) return GCD(a, b / 2);
return GCD(b, (a - b).abs);
</source>
|