110 likes | 214 Views
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
E N D
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(n2 )
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)
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(n3)
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(n2)
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 ≈ N2 • Složitost je: f O(n2) • 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*log2N2 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*log2N2 kroků) 2. projdi seznam P1 a nalezni nejdelší úsek bez značky (N1 kroků) Celkem: N2*log2N2 + N1*log2N2 + N1 ≤ 2*N*log2N + N ≈ N*log2N • Složitost je: f O(n*log2n)