Algorytm Euklidesa

Przypomnijmy: algorytm Euklidesa stosowany jest do wyznaczania największego wspólnego dzielnika (NWD) dwóch liczb naturalnych. NWD może być wykorzystany do skracania ułamków czy obliczania najmniejszej wspólnej wielokrotności (NWW). Więcej na temat tego algorytmu przeczytasz w tym podręczniku w e‑materiale: Algorytm Euklidesa.

Specyfikacja problemu:

Dane

  • a – liczba naturalna

  • b – liczba naturalna

Wynik

  • NWD liczb ab

Algorytm Euklidesa z odejmowaniem

Wersja rekurencyjna prezentuje się następująco:

Linia 1. funkcja NWD otwórz nawias okrągły a przecinek b zamknij nawias okrągły. Linia 2. jeżeli a wykrzyknik znak równości b dwukropek. Linia 3. jeżeli a zamknij nawias ostrokątny b. Linia 4. zwróć NWD otwórz nawias okrągły a minus b przecinek b zamknij nawias okrągły. Linia 5. w przeciwnym razie. Linia 6. zwróć NWD otwórz nawias okrągły a przecinek b minus a zamknij nawias okrągły. Linia 7. zwróć a.

Funkcje są rekurencyjnie wywoływane do momentu, gdy wartości argumentów funkcji będą takie same. Wtedy zwracana jest wartość jednego z nich i to on jest największym wspólnym dzielnikiem liczb a oraz b.

Algorytm Euklidesa opiera się na prostej obserwacji: jeżeli liczba naturalna c dzieli liczby naturalne ab, to dzieli również ich różnicę. Rzeczywiście jeśli c = NWD(a, b), wówczas istnieją takie względnie pierwsze liczby naturalne kl, dla których a = c * k oraz b = c * l. Niech ponadto a > b. Wówczas a - b = c * k - c * l = c * (k - l), co oznacza, że liczba a - b również dzieli się przez c. To oznacza, że zarówno różnica liczb b oraz a - b, jak i różnica liczb a oraz a - b dzielą się przez c. Powtarzanie odejmowania doprowadzi do obliczenia c.

Algorytm Euklidesa z resztą z dzielenia

W tym wariancie algorytmu do znalezienia NWD – zamiast różnicy dwóch liczb – używa się reszty z ich dzielenia.

W podejściu rekurencyjnym dla b różnego od 0 przykładowa funkcja NWD(a, b) wywołuje samą siebie z argumentami NWD(b, a mod b) do momentu trafienia na przypadek podstawowy, kiedy b będzie równe 0. Pseudokod takiej funkcji wygląda następująco:

Linia 1. funkcja NWD otwórz nawias okrągły a przecinek b zamknij nawias okrągły dwukropek. Linia 2. jeżeli a wykrzyknik znak równości 0 dwukropek. Linia 3. zwróć NWD otwórz nawias okrągły b mod a przecinek a zamknij nawias okrągły. Linia 4. w przeciwnym razie. Linia 5. zwróć b.

Funkcje są rekurencyjnie wywoływane do momentu, gdy wartość jednego argumentu funkcji jest równa 0. Wtedy zwracana jest wartość jednego z nich i to on jest największym wspólnym dzielnikiem liczb a oraz b.

Zastanówmy się, dlaczego możemy w ten sposób podejść do tego problemu.

Załóżmy, że chcemy obliczyć NWD dwóch liczb a oraz b. Są to liczby naturalne. Chcemy wyznaczyć liczbę c, która jest ich największym wspólnym dzielnikiem.

W naszym problemie a ≤ b. Podzielmy b przez a. Otrzymamy iloraz (x) oraz resztę (r). Zapiszmy to.

b ÷ a = x reszta r

Zatem:

b = ax + r

natomiast:

0  r < m

Jeśli r = 0, to NWD(a, b) = a. Oznacza to, że jedna z liczb dzieli drugą bez reszty, zatem mniejsza z liczb jest wspólnym dzielnikiem.

Jeśli natomiast r ≠ 0, możemy zapisać, że r = b - xa. Możemy zatem zauważyć, że każda liczba, która dzieli liczby a oraz b, dzieli również całe wyrażenie b - xa, zatem dzieli również r. Wynika z tego to, że NWD liczb a oraz b dzieli również resztę r.

Możemy to zapisać jako NWD(a, b) = NWD(r, a), a ponieważ reszta z dzielenia jest wynikiem operacji modulo, to NWD(a, b) = NWD(b mod a, a).

Słownik

iteracja
iteracja

technika programowania polegająca na powtarzaniu tych samych operacji w pętli określoną liczbę razy lub do momentu, aż zostanie spełniony zadany warunek

NWD
NWD

największy wspólny dzielnik dwóch liczb – największa liczba naturalna, która dzieli obie te liczby bez reszty

przepełnienie pamięci
przepełnienie pamięci

błąd polegający na przekroczeniu rozmiaru zarezerwowanego miejsca dla programu w pamięci operacyjnej

rekurencja
rekurencja

technika programowania polegająca na odwoływaniu się procedur lub funkcji do samych siebie, aż do momentu spełnienia warunku podstawowego

stos
stos

dynamiczna struktura danych, w której informacje pobierane są ze szczytu i na niego odkładane; struktura typu LIFO (Last‑In, First‑Out – ostatni na wejściu, pierwszy na wyjściu)

liczby względnie pierwsze
liczby względnie pierwsze

liczby całkowite, których największym wspólnym dzielnikiem jest liczba jeden