«наибольший общий делитель двух чисел не изменяется, если большее число заменяется его разность с меньшим числом.»
(wikipedia - Euclidean algorithm)
Таким образом, по модулю:
Модульное возвращает остаток от целочисленного между двумя дивизия целых чисел. Целочисленное деление - это деление без дробей или плавающих точек. Обозначим целочисленное деление как m /\ n
.
m /\ n = o;
m % n = p;
o * n + p = m;
В качестве примера,
29 /\ 3 = 9; (3 goes - whole - into 29 9 times)
29 % 3 = 2; (the integer division of 29 into 3 has a remainder of 2)
9 * 3 + 2 = 29; (9 goes into 29 3 times (and 3 goes into 29 9 times), with a remainder of 2)
Обратите внимание, что если m
меньше n
(т.е. m < n
), то n
переходит в m
0 раз (m /\ n = 0
), так что остаток от целочисленного деления будет be m
(m % n = m
, потому что o * n + p = m
и так (0*n) + p = 0 + p = p = m
);
Итак, как работает эта функция? давайте попробуем его использовать.
1 - НОД (т, п), м < п
Таким образом, если мы начинаем gcd(m, n)
с m
, который меньше, чем n
, единственное, что происходит на следующем вложенном вызове НОД является то, что порядок изменений аргументов: gcd(n, m % n) = gcd(n, m)
;
2 - НОД (п, м), м < п
Итак, теперь первый аргумент больше второго.
Согласно алгоритму Евклида, мы хотим сделать что-то большее для двух чисел. Мы хотим заменить его разницей между ним и меньшим числом. Мы могли бы сделать m - n
кучу раз. Но то, что делает m % n
, является таким же, как вычитание n
от m
столько раз, сколько возможно до, поэтому это приведет к отрицательному числу. Выполнение вычитания будет выглядеть как (((m - n) - n) - n) - n)
и так далее. Но если мы расширим это, получим: m - (n * o)
. Потому что o * n + p = m
, мы видим, что m - (n * o) = p
и p = m % n
. Таким образом, многократное вычитание меньшего из большего числа такое же, как и для модуля большего размера с меньшим.
На следующем этапе второй аргумент может быть 0 (если n
был делителем m
). В этом случае функция возвращает n. это верно, потому что n является делителем самого себя, а также, как мы видели, делителем m
.
Или второй аргумент может быть меньше n
. Это связано с тем, что остаток от целочисленного деления m
до n
должен быть меньше n
- это связано с тем, что если остаток деления был больше n
, то n
мог бы поместиться в m
еще раз, ; это абсурдный результат. Предполагая, что n
не равен 0, то второй аргумент (назовем его p
) меньше n
.
Итак, теперь мы звоним gcd(n, p)
, где p < n
.
3 - НОД (п, р), р < п
Что происходит сейчас? ну, мы точно в том же месте, что и в предыдущем абзаце. Теперь мы просто повторяем этот шаг, т. Е. Будем продолжать называть gcd(a, b)
, пока меньшее из двух чисел, переданных в gcd(a ,b)
, не будет делителем большего из двух чисел (это означает, что a % b = 0
), и в этом случае вы просто возвращаете меньше из двух чисел.
Узнайте о рекурсии, и это будет ясно для вас. –
1) 'a% b' является mod b в нормальных математических обозначениях. 2) Вы не возвращаете два значения, вы рекурсируете; Узнайте больше о рекурсии. –