Cvičení Úloha 1: Rozhodněte zda posloupnost znaků v poli délky n tvoří palindrom (slovo, které je stejné při čtení zprava i zleva). Př.: [a,l,e,l,a] [a,n,n,a] [k,r,k] [i,d,o,l,z,l,o,d,i] Navrhněte vhodný algoritmus pro tuto úlohu Určete složitost navrženého algoritmu Navrhněte případně algoritmus rychlejší
Palindrom Algoritmus 1: 1. jestliže je seznam prázdný nebo jednoprvkový, potom skonči úspěšně 2. vezmi první prvek seznamu, smaž ho a jdi na konec seznamu ověřit, zda je tam tentýž prvek; jestliže ano také ho smaž, jinak konec 3. pokračuj krokem číslo 1 palindrom([]) :- !. palindrom([H]) :- !. palindrom([H|T]) :- kontrola(H, T, T1), !, palindrom(T1). kontrola(H, [H], []) :- !. kontrola(H, [C|T], [C|T1]) :- kontrola(H, T, T1). Pro 1. prvek dělám n kroků, potom n-2, n-4, … Složitost je tedy: f O(n 2 )
Palindrom Algoritmus 2: 1. otoč seznam 2. postupně porovnávej prvky v původním a otočeném seznamu palindrom([]) :- !. palindrom2(Sez) :- reverse(Sez, S1), kontroluj(Sez, S1), !. kontroluj([], []) :- !. kontroluj([H|T], [H|T1]) :- kontroluj(T, T1). Otočení proběhne v lineárním čase Kontrola proběhne také v lineárním čase Složitost je tedy: f O(n)
Palindrom Praktický rozdíl mezi použitím algoritmu 1 a 2 na seznamu o velikosti N: (čas je uveden ve formátu min:sec:ssec) N Algoritmus 1 O(n 2 ) Algoritmus 2 O(n) : 06 : 5900 : 00 : : 49 : 9500 : 00 : : 08 : 6300 : 00 : : 51 : 6300 : 00 : 01
Cvičení 2 Úloha 2: V zadané posloupnosti reálných čísel délky N nalezněte úsek s maximálním součtem. Př.: 1,3,5,-8,4,-7,15,3,-12,-8,7,-1,9,4,-6,-14,3,5,4,-17,11 Navrhněte vhodný algoritmus pro tuto úlohu Určete složitost navrženého algoritmu Navrhněte případně algoritmus rychlejší
Posloupnost Algoritmus 1: max:=0; for i=1 to n do for j=i to n do pom:=0; for k=i to j do pom := pom+a[k]; if pom > max then max := pom; Zkoumá všechny možné začátky a konce úseků Mezi nimi provede součet prvků Tři do sebe vnořené cykly; složitost je: f O(n 3 )
Posloupnost Algoritmus 2: max:=0; for i=1 to n do pom:=0; for j=i to n do pom := pom+a[j]; if pom > max then max := pom; Pro každý začátek zkoušíme počítat součty všech úseků Zbavili jsme se jednoho cyklu Složitost je: f O(n 2 )
Posloupnost Algoritmus 3: max:=0; pom:=0; for i=1 to n do pom := pom+a[i]; if pom > max then max := pom else if pom < 0 then pom := 0 Úsek s maximálním součtem musí začínat kladným číslem; pokud při načítání klesneme pod nulu, je čas začít znovu Zbavili jsme se dalšího cyklu Složitost je: f O(n)
Cvičení 3 Úloha 3: V zadané posloupnosti reálných čísel P1 délky N1 nalezněte nejdelší úsek, který neobsahuje žádný prvek z druhé zadané posloupnosti P2 o délce N2. Př.: P1: 1,3,5,-8,4,-7,15,3,-12,-8,7,-1,9,4,-6,-14,3,5,4 P2: 3,11,4,25,-12,-1,5,41,17,-22,13 Navrhněte vhodný algoritmus pro tuto úlohu Určete složitost navrženého algoritmu Navrhněte případně algoritmus rychlejší
Dva seznamy Algoritmus 1: 1. procházej seznam P1, pro každý prvek ověř, zda je i v P2 a pokud ano, nahraď jej vhodnou značkou (N1*N2 kroků) 2. projdi seznam P1 a nalezni nejdelší úsek bez značky (N1 kroků) Celkem: N1*N2 + N1 ≈ N 2 Složitost je: f O(n 2 ) Jsou-li seznamy dlouhé, vyplatí se zvážit datovou strukturu seznamu P2, ve kterém často vyhledávám
Dva seznamy Algoritmus 2: 1. Převeď seznam P2 na binární strom (N2*log 2 N2 kroků) 2. procházej seznam P1, pro každý prvek ověř, zda je i v P2 (strom) a pokud ano, nahraď jej vhodnou značkou (N1*log 2 N2 kroků) 2. projdi seznam P1 a nalezni nejdelší úsek bez značky (N1 kroků) Celkem: N2*log 2 N2 + N1*log 2 N2 + N1 ≤ 2*N*log 2 N + N ≈ N*log 2 N Složitost je: f O( n*log 2 n)