Algorytm Euklidesa/kod
Z Wikiźródeł, repozytorium wolnych materiałów źródłowych
| Algorytm Euklidesa Kod źródłowy |
|||
Implementacje algorytmu Euklidesa.
|
- C/C++, C#, Java:
int nwd(int a, int b) { if (b == 0) { return a; } return nwd(b, (a % b)); }
- PHP:
function NWD($a, $b) { while ($b) { $tmp = $a%$b; $a = $b; $b = $tmp; } return $a; }
function nwd(a, b: Integer): Integer; var tmp: Integer; begin repeat tmp := a mod b; a := b; b := tmp; until b = 0; nwd := a; end;
def nwd(a, b): while b: a, b = b, a%b return a
sub nwd { my ($a,$b)=@_; # drugi argument nie powinien być większy od pierwszego ($b,$a)=($a,$b) if $b>$a; return $a if $b==0; nwd($b,$a%$b); };
- Java:
class Nwd{
public static int nwd(int a, int b)
{
int tmp=0;
while (b!=0)
{
tmp = a%b;
a = b;
b = tmp;
}
return a;
}
}
CREATE FUNCTION NWD(@a int, @b int) returns int AS begin declare @tmp int while @b <> 0 SELECT @tmp = @a%@b, @a = @b, @b = @tmp RETURN @a end
#!/bin/bash echo -n "Podaj a: "; read A echo -n "Podaj b: "; read B a=$A; b=$B while [ $b != "0" ]; do ((c = a % b)) a=$b; b=$c done echo "NWD($A, $B) = $a"
Euklides pierwotnie sformułował ten problem geometrycznie, jako szukanie wspólnej "miary" dwóch odcinków. Jego algorytm polegał na kolejnym odejmowaniu krótszego odcinka od dłuższego. Można to zilustrować następującą implementacją Pascalu.
function nwd(a,b: Integer): Integer; begin while a <> b do if a > b then a := a-b else b := b-a; nwd := a; end;
- Wersja z odejmowaniem "odcinków" w Pythonie.
def nwd(a,b): while a != b: if a > b: a -= b else: b -= a return a
nwd(X,0,X). nwd(X,Y,Wynik):- not(Y==0), X1 is X mod Y, nwd(Y,X1,Wynik1), Wynik is Wynik1.
- Scheme (definicja funkcji wynika bezpośrednio ze wzoru rekurencyjnego):
(define (nwd a b) (if (= b 0) a (nwd b (modulo a b))))
Dla większej ilości liczb sprawdza się następujący algorytm (język PHP):
function gcdp($a, $b) { // funkcja pomocnicza if ($b == 0) { return $a; } else { return gcdp($b, $a % $b); } } function gcd($list) { // główna funkcja sort($list); $g = $list[0]; for ($i = 0; $i < count($list)-1; $i++) { $g = gcdp($g, $list[$i]); } return $g; }
NWD w języku Pascal
function nwd (a,b :integer) :integer; {funkcja licząca największy wspólny dzielnik przy pomocy algorytmu euklidesa, wersja nierekursywna} var c:integer; {robocza} begin c:=a mod b; {dla ustalenia początkowej wartości c, zakładamy że b<>0} while c<>0 do begin c:=a mod b; a:=b; b:=c; end; {while} nwd:=a; end;
Poniżej znajduje się inny algorytm, który jest zapisany w języku Ruby.
def bgcd(a,b) g=1 while(a&1==0 && b&1==0) g<<=1 a>>=1 b>>=1 end while b!=0 if a&1 == 0 a>>=1 elsif b&1 == 0 b>>=1 else if (a>b) a-=b a>>=1 else b-=a b>>=1 end end end return g*a end
Kolejny algorytm, również w języku Ruby.
dla dwóch liczb
def nwd(a,b) if a > b then a -= b else b -= a end while a != b; return a end </pre> dla wielu liczb gdzie ''arr'' - tablica liczb <pre> def nwd(arr) a = arr.pop arr.each do |b| if a > b then a -= b else b -= a end while a != b; end return a end
Prosty algorytm wyznaczający NWD zapisany w języku Python:
def nwd(a,b): while a != b: if a > b: a = a - b else: b = b - a return a
Powyższy algorytm (taki sam jak NWD w ActionScript) staje się pętlą nieskończoną gdy
lub
(w przeciwieństwie do poniższych algorytmów w C / C++).
Funkcja w C / C++ znajdująca NWD dwóch podanych w argumencie liczb:
/*Funkcja przyjmuje 2 liczby naturalne i zwraca NWD*/ int nwd(int a, int b) { int wynik; for(; ;) // lub while(true), while(1) { if (b!=0) { wynik = a % b; a = b; b = wynik; } else if (b==0) { wynik = a; break; } } return wynik; } //lub rekurencyjna: int nwd(int m, int n){ if (n!=0) return nwd(n, m%n); return m; }
NWD w Scheme`ie
(define (mod a b) (if(< a b) a (mod (- a b) b))) (define (nwd a b) (if(=? b 0) a (nwd b (mod a b))))
NWD w symulatorze MARIE
Input / AC = wejscie Store X / X = AC Input / AC = wejscie Store Y / Y = AC While, Load X / AC = X Subt Y / AC -= Y Skipcond 400 / If (AC==0) [X!=Y] to pomin nast. rozkaz Jump If / If (X!=Y) skocz do If Jump Return / If (X==Y) to wyjdz z petli If, Skipcond 800 / If (AC>0) [X>Y] to pomin nast. rozkaz Jump Else / If (X<Y) to skocz do Else Load X / AC = X Subt Y / AC -= Y Store X / X = AC Jump While / skocz do While (petla) Else, Load Y / AC = Y Subt X / AC -= X Store Y / Y = AC Jump While / skocz do While (petla) Return, Load X / AC = X Output / daj AC na wyjscie Halt / koniec X, dec 0 Y, dec 0
NWD w ActionScript:
function nwd(a, b) { while (a != b) { if (a>b) { a -= b; } else { b -= a; } } return a; }
[edytuj] Rozszerzony algorytm Euklidesa
CREATE FUNCTION nwd(@a int, @b int) returns @m TABLE(p int, q int) /* Funkcja zwraca rozwiązanie równania: a*p + b*q = NWD(a,b) */ AS begin declare @r int, @q int, @x int, @x1 int, @x2 int, @y int, @y1 int, @y2 int SELECT @q = @a/@b, @r = @a - @q*@b, @x2 = 1, @x1 = 0, @x = 1, @y2 = 0, @y1 = 1, @y = 1 - @q while @r <> 0 SELECT @a = @b, @b = @r, @x = @x2 - @q*@x1, @x2 = @x1, @x1 = @x, @y = @y2 - @q*@y1, @y2 = @y1, @y1 = @y, @q = @a/@b, @r = @a - @q*@b INSERT INTO @m SELECT @x, @y RETURN end
#include <iostream.h> #include <math.h> int main (){ int a,b; //Pobranie danych cout << "Podaj a "; cin >> a; cout << "\nPodaj b "; cin >> b; if ( (a < 0) || (b < 0) ){ cout << "Wartosci a i b powinny byc wieksze od zera\n"; exit (1); } //zachowanie pierwotnych wartosci int a0 = a, b0 = b; //Zapewnia spelnienie niezmiennika p*a0 + q*b0 = a oraz r*a0 + s*b0 = b int p = 1, q = 0, r = 0, s = 1; int c,quot,new_r,new_s; //algorytm while (b != 0){ c = a % b; quot = lrint (floor (a/b)); a = b; b = c; new_r = p - quot * r; new_s = q - quot * s; p = r; q = s; r = new_r; s = new_s; } cout << "NWD(a,b) = a * p + b * q\n" << "NWD(" << a0 << "," << b0 << ") = " << a0 << " * " << p << " + " << b0 << " * " << q << endl; }
#include <cstdio> int v,w; template <class _t1, class _t2, class _t3> struct tripl { // wzorowane na kontenerze pair z biblioteki STL _t1 d; _t2 x; _t3 y; tripl() : d(), x(), y() { }; tripl(const _t1& _a, const _t2& _b, const _t3& _c) : d(_a), x(_b), y(_c) { }; template <class _u1, class _u2, class _u3> tripl(const tripl<_u1,_u2,_u3>& _t) : d(_t.d), x(_t.x), y(_t.y) { }; }; template <class typ> tripl<typ,typ,typ> egcd(typ _a, typ _b) { // szablon funkcji obliczającej NWD if(_b==0) return tripl<typ,typ,typ>(_a,1,0); tripl<typ,typ,typ> tmp; tmp = egcd<typ>(_b,_a%_b); return tripl<typ,typ,typ>(tmp.d,tmp.y,tmp.x-((int)(_a/_b))*tmp.y); } int main() { printf("Podaj pare liczb rozdzielonych spacja\n"); scanf("%d%d",&v,&w); tripl<int,int,int> ret; ret = egcd(v,w); printf("gcd(%d,%d) = %d = %d*%d %c %d*%d\n", v,w,ret.d,ret.x,v,ret.y>0?'+':'-',ret.y>0?ret.y:-ret.y,w); return 0; }

