Twoje dwa algorytmy są równoważne (przynajmniej w przypadku liczb całkowitych dodatnich to, co dzieje się z liczbami całkowitymi ujemnymi w wersji rozkazującej, zależy od semantyki Javy, dla %
której nie znam na pamięć). W wersji rekurencyjne, niech I a b I jako argument I th wywołanie rekurencyjne:
i + 1 = b I b i + 1 = I m o d b Izajabjaja
zai + 1= bjabi + 1= ajam o d bja
W wersji imperatywu, niech ' ja i b ' i być wartości zmiennych i na początku í th iteracji pętli.
a ′ i + 1 = b ′ i b ′ i + 1 = a ′ i m o d b ′ iza′jab′jaa
b
ja
za′i + 1= b′jab′i + 1= a′jam o d b′ja
Czy zauważyłeś podobieństwo? Twoja wersja imperatywna i wersja rekurencyjna obliczają dokładnie te same wartości. Ponadto oba kończy w tym samym czasie, gdy i = 0 (wzgl. " I = 0 ), tak, że wykonują ten sam liczby iteracji. Algorytmicznie rzecz biorąc, nie ma między nimi żadnej różnicy. Wszelkie różnice będą zależeć od implementacji, w dużej mierze zależnej od kompilatora, sprzętu, na którym działa, a być może nawet systemu operacyjnego i innych programów działających jednocześnie.zaja= 0za′ja= 0
Wersja rekurencyjna wykonuje tylko połączenia rekurencyjne z tyłu . Większość kompilatorów dla języków imperatywnych nie optymalizuje ich, więc jest prawdopodobne, że generowany przez nich kod będzie marnował trochę czasu i pamięci na tworzenie ramki stosu przy każdej iteracji. Dzięki kompilatorowi, który optymalizuje wywołania ogonowe (kompilatory dla języków funkcjonalnych prawie zawsze tak robią), wygenerowany kod maszynowy może być taki sam dla obu (zakładając, że zharmonizujesz te wywołania abs
).