E005. Extended Euclidean algorithm

e-maxx algorithm original: C/C++ #algorithm #emaxx #math #number-theory
선택한 UI 언어에 맞게 문제 텍스트를 러시아어에서 번역합니다. 코드는 변경하지 않습니다.

Источник: e-maxx.ru/algo, страница PDF 18.

В то время как "обычный" Euclidean algorithm просто находит наибольший общий делитель двух чисел

и

,

Extended Euclidean algorithm находит помимо НОД также коэффициенты

и

такие, что: Т.е. он находит коэффициенты, с помощью которых НОД двух чисел выражается через сами эти числа.

알고리즘

Внести вычисление этих коэффициентов в Euclidean algorithm несложно, достаточно вывести формулы, по которым

они меняются при переходе от пары

к паре

(знаком процента мы обозначаем взятие остатка

от деления).

Итак, пусть мы нашли 해법

задачи для новой пары

:

и хотим получить 해법

для нашей пары

:

Для этого преобразуем величину

:

Подставим это в приведённое выше выражение с

и

и получим: и, выполняя перегруппировку слагаемых, получаем:

Сравнивая это с исходным выражением над неизвестными

и

, получаем требуемые выражения:

구현

int gcd (int a, int b, int & x, int & y) {
if (a == 0) {

x = 0; y = 1;

return b;

}

int x1, y1;
int d = gcd (b%a, a, x1, y1);

x = y1 - (b / a) * x1;

y = x1;

return d;

} Это рекурсивная функция, которая по-прежнему returns значение НОД от чисел

и

, но помимо этого —

также искомые коэффициенты

и

в виде параметров функции, передающихся по ссылкам.

База рекурсии — случай

. Тогда НОД равен

, и, очевидно, требуемые коэффициенты

и

равны

и

соответственно. В остальных случаях работает обычное 해법, а коэффициенты пересчитываются по вышеописанным формулам. Extended Euclidean algorithm в такой реализации работает корректно даже для отрицательных чисел.

References

● Томас Кормен, Чарльз Лейзерсон, Рональд Ривест, Клиффорд Штайн. 알고리즘ы: Построение и

анализ [2005]

C# 해법

자동 초안, 제출 전 검토
using System;
using System.Collections.Generic;
using System.Linq;

public static class AlgorithmDraft
{
    // Auto-generated C# draft from the original e-maxx C/C++ listing. Review before production use.
    int gcd (int a, int b, int & x, int & y) {
            if (a == 0) {
                    x = 0; y = 1;
                    return b;
            }
            int x1, y1;
            int d = gcd (b%a, a, x1, y1);
            x = y1 - (b / a) * x1;
            y = x1;
            return d;
    }
}

C++ 해법

매칭됨/원본
int gcd (int a, int b, int & x, int & y) {
        if (a == 0) {
                x = 0; y = 1;
                return b;
        }
        int x1, y1;
        int d = gcd (b%a, a, x1, y1);
        x = y1 - (b / a) * x1;
        y = x1;
        return d;
}

Java 해법

자동 초안, 제출 전 검토
import java.util.*;
import java.math.*;

public class AlgorithmDraft {
    // Auto-generated Java draft from the original e-maxx C/C++ listing. Review before production use.
    int gcd (int a, int b, int & x, int & y) {
            if (a == 0) {
                    x = 0; y = 1;
                    return b;
            }
            int x1, y1;
            int d = gcd (b%a, a, x1, y1);
            x = y1 - (b / a) * x1;
            y = x1;
            return d;
    }
}

Материал разбит как 알고리즘ическая 문제: изучить постановку, понять асимптотику и реализовать 알고리즘 на выбранном языке.

Vacancies for this task

활성 채용 with overlapping task tags are 표시됨.

전체 채용
아직 활성 채용이 없습니다.