За да не бъде изключително скучен този пост, ще ви спомена как да намерим и НОК (най-малко общо кратно - т.е., най-малкото число, което се дели на няколко други числа и е тяхно "кратно"). 😉
---
Кой не обича math jokes... :) |
ОПИСАНИЕ:
Двоичният алгоритъм за намиране на НОД (понякога наричан Stein's algorithm - алгоритъм на Стайн, Стейн, Щайн... кой знае?) използва набор от правила, с които намалява изчисленията по намирането на НОД.
Ще отбележим 2-те числа, на които търсим НОД, с 'u' и 'v'.
Алгоритъмът изисква време пропорционално на квадрата на общия брой на битове, които 'u' и 'v' заемат. Въпреки че поне едно от числата се редуцира на всяка стъпка, изваждането и преместването не се извършват за константно време всеки път (особено за много големи числа) , но все пак на практика те са доста бързи операции.
(последният параграф взет от дадените ми лекции по Проектиране и анализ на алгоритми :))
АЛГОРИТЪМ:
НОД (u, v) = ?
1) НОД(0, v) = v
2) НОД(u, 0) = u
4) u - четно, v - нечетно
5) u - нечетно, v - четно
-> НОД(u,v) = НОД(u, v/2)
6) u, v - нечетни
- u >= v
-> НОД(u,v) = НОД( (u-v)/2, v )
- v > u
-> НОД(u,v) = НОД( u, (v-u)/2 )
АЛГОРИТЪМ:
НОД (u, v) = ?
1) НОД(0, v) = v
2) НОД(u, 0) = u
* НОД(0, 0) е неопределен.
3) u, v - четни
-> НОД(u,v) = 2 * НОД (u/2, v/2)
3) u, v - четни
-> НОД(u,v) = 2 * НОД (u/2, v/2)
4) u - четно, v - нечетно
-> НОД(u,v) = НОД(u/2, v)
5) u - нечетно, v - четно
-> НОД(u,v) = НОД(u, v/2)
6) u, v - нечетни
- u >= v
-> НОД(u,v) = НОД( (u-v)/2, v )
- v > u
-> НОД(u,v) = НОД( u, (v-u)/2 )
Намиране на НОК (бонус алгоритъм):
ПРИМЕР:
Ето няколко примера, които илюстрират как точно се прилага двоичният алгоритъм на всяка стъпка.
Смятам, че няма нужда от обяснения този път. 😄
===
НОД(728, 140) =
= 2 * НОД(364, 70) =
= 2 * 2 * НОД(182, 35) =
= 2 * 2 * НОД(91, 35) =
= 2 * 2 * НОД( (91-35)/2, 35 ) =
= 2 * 2 * НОД(56/2, 35)
= 2 * 2 * НОД(28, 35) =
= 2 * 2 * НОД(28/2, 35) =
= 2 * 2 * НОД(14, 35) =
= 2 * 2 * НОД(14/2, 35) =
= 2 * 2 * НОД(7, 35) =
= 2 * 2 * НОД( 7, (35-7)/2 ) =
= 2 * 2 * НОД(7, 28/2) =
= 2 * 2 * НОД(7, 14) =
= 2 * 2 * НОД(7, 14/2) =
= 2 * 2 * НОД(7, 7) =
= 2 * 2 * НОД( (7-7)/2, 7) ) =
= 2 * 2 * НОД(0, 7) =
= 2 * 2 * 7 =
= 28
===
НОД(2505, 9775) =
= НОД( 2505, (9775-2505)/2 ) =
= НОД(2505, 7270/2)
= НОД(2505, 3635)
= НОД( 2505, (3635-2505)/2 ) =
= НОД(2505, 1130/2) =
= НОД(2505, 565)
= НОД( (2505-565)/2, 565) =
= НОД(1940/2, 565) =
= НОД(970, 565) =
= НОД(970/2, 565) =
= НОД(485, 565) =
= НОД( 485, (565-485)/2) ) =
= НОД(485, 80/2) =
= НОД(485, 40) =
= НОД(485, 40/2) =
= НОД(485, 20) =
= НОД(485, 20/2) =
= НОД(485, 10) =
= НОД(485, 10/2) =
= НОД(485, 5) =
= НОД( (485-5)/2, 5 ) =
= НОД(480/2, 5) =
= НОД(240, 5) =
= НОД(240/2, 5) =
= НОД(120, 5) =
= НОД(120/2, 5) =
= НОД(60, 5) =
= НОД(60/2, 5) =
= НОД(30, 5) =
= НОД(30/2, 5) =
= НОД(15, 5) =
= НОД( (15-5)/2, 5) =
= НОД(10/2, 5) =
= НОД(5, 5) =
= НОД( (5-5)/2, 5 ) =
= НОД(0, 5) =
= 5
===
НОД(10127, 8323) =
= НОД( (10127-8323)/2, 8323 ) =
= НОД(1804/2, 8323) =
= НОД(902, 8323) =
= НОД(902/2, 8323) =
= НОД(451, 8323) =
= НОД( 451, (8323-451)/2 ) =
= НОД(451, 7872/2) =
= НОД(451, 3936) =
= НОД(451, 3936/2) =
= НОД(451, 1968) =
= НОД(451, 1968/2) =
= НОД(451, 984) =
= НОД(451, 984/2) =
= НОД(451, 492) =
= НОД(451, 492/2) =
= НОД(451, 246) =
= НОД(451, 246/2) =
= НОД(451, 123) =
= НОД( (451-123)/2, 123 ) =
= НОД(328/2, 123) =
= НОД(164, 123) =
= НОД(164/2, 123) =
= НОД(82, 123) =
= НОД(82/2, 123) =
= НОД(41, 123) =
= НОД( 41, (123-41)/2 ) =
= НОД(41, 82/2) =
= НОД(41, 41) =
= НОД( (41-41)/2, 41 ) =
= НОД(0, 41) =
= 41
ИМПЛЕМЕНТАЦИЯ (Java):
Намиране на НОК:
---
Това е за днес! Ако видите някоя грешка - сигнализирайте ми! 😉
Намирането на НОК става изключително лесно след като знаем НОД на 2-те числа. Прилагаме формулата:
НОК(a, b) = (a * b) / НОД(a, b)
За повече от 2 числа, прилагаме НОК(a, b, c) = НОК(а, НОК(b, c)).
ПРИМЕР:
Ето няколко примера, които илюстрират как точно се прилага двоичният алгоритъм на всяка стъпка.
Смятам, че няма нужда от обяснения този път. 😄
===
НОД(728, 140) =
= 2 * НОД(364, 70) =
= 2 * 2 * НОД(182, 35) =
= 2 * 2 * НОД(91, 35) =
= 2 * 2 * НОД( (91-35)/2, 35 ) =
= 2 * 2 * НОД(56/2, 35)
= 2 * 2 * НОД(28, 35) =
= 2 * 2 * НОД(28/2, 35) =
= 2 * 2 * НОД(14, 35) =
= 2 * 2 * НОД(14/2, 35) =
= 2 * 2 * НОД(7, 35) =
= 2 * 2 * НОД( 7, (35-7)/2 ) =
= 2 * 2 * НОД(7, 28/2) =
= 2 * 2 * НОД(7, 14) =
= 2 * 2 * НОД(7, 14/2) =
= 2 * 2 * НОД(7, 7) =
= 2 * 2 * НОД( (7-7)/2, 7) ) =
= 2 * 2 * НОД(0, 7) =
= 2 * 2 * 7 =
= 28
===
НОД(2505, 9775) =
= НОД( 2505, (9775-2505)/2 ) =
= НОД(2505, 7270/2)
= НОД(2505, 3635)
= НОД( 2505, (3635-2505)/2 ) =
= НОД(2505, 1130/2) =
= НОД(2505, 565)
= НОД( (2505-565)/2, 565) =
= НОД(1940/2, 565) =
= НОД(970, 565) =
= НОД(970/2, 565) =
= НОД(485, 565) =
= НОД( 485, (565-485)/2) ) =
= НОД(485, 80/2) =
= НОД(485, 40) =
= НОД(485, 40/2) =
= НОД(485, 20) =
= НОД(485, 20/2) =
= НОД(485, 10) =
= НОД(485, 10/2) =
= НОД(485, 5) =
= НОД( (485-5)/2, 5 ) =
= НОД(480/2, 5) =
= НОД(240, 5) =
= НОД(240/2, 5) =
= НОД(120, 5) =
= НОД(120/2, 5) =
= НОД(60, 5) =
= НОД(60/2, 5) =
= НОД(30, 5) =
= НОД(30/2, 5) =
= НОД(15, 5) =
= НОД( (15-5)/2, 5) =
= НОД(10/2, 5) =
= НОД(5, 5) =
= НОД( (5-5)/2, 5 ) =
= НОД(0, 5) =
= 5
===
НОД(10127, 8323) =
= НОД( (10127-8323)/2, 8323 ) =
= НОД(1804/2, 8323) =
= НОД(902, 8323) =
= НОД(902/2, 8323) =
= НОД(451, 8323) =
= НОД( 451, (8323-451)/2 ) =
= НОД(451, 7872/2) =
= НОД(451, 3936) =
= НОД(451, 3936/2) =
= НОД(451, 1968) =
= НОД(451, 1968/2) =
= НОД(451, 984) =
= НОД(451, 984/2) =
= НОД(451, 492) =
= НОД(451, 492/2) =
= НОД(451, 246) =
= НОД(451, 246/2) =
= НОД(451, 123) =
= НОД( (451-123)/2, 123 ) =
= НОД(328/2, 123) =
= НОД(164, 123) =
= НОД(164/2, 123) =
= НОД(82, 123) =
= НОД(82/2, 123) =
= НОД(41, 123) =
= НОД( 41, (123-41)/2 ) =
= НОД(41, 82/2) =
= НОД(41, 41) =
= НОД( (41-41)/2, 41 ) =
= НОД(0, 41) =
= 41
ИМПЛЕМЕНТАЦИЯ (Java):
Намиране на НОК:
---
Това е за днес! Ако видите някоя грешка - сигнализирайте ми! 😉
Няма коментари:
Публикуване на коментар