Kdybychom takový automat mìli, mohli bychom pomocí nìj inkrementální algoritmus
z~pøedchozí sekce popsat následovnì:
-\s{Krok($I$, $x$):} \cmt{Jeden krok automatu: jsme ve stavu~$I$, pøeèetli jsme znak~$x$.}
-\algo
+\proc{KmpKrok} \cmt{Jeden krok automatu}
+\algin Jsme ve~stavu~$I$, pøeèetli jsme znak~$x$.
\:Dokud $\iota[I] \neq x~\&~I \neq 0: I \= Z[I]$.
\:Pokud $\iota[I] = x$, pak $I \= I + 1$.
-\:Vrátíme nový stav~$I$.
+\algout Nový stav~$I$.
\endalgo
-\s{Hledej($\sigma$):} \cmt{Spu¹tìní automatu na øetìzec~$\sigma$.}
-\algo
+\algo{Kmp} \cmt{Spu¹tìní automatu na øetìzec~$\sigma$.}
+\algin Seno~$\sigma$, zkonstruovaný automat.
\:$I \= 0$.
\:Pro znaky $x\in\sigma$ postupnì provádíme:
-\::$I \= \<Krok>(I,x)$.
+\::$I \= \alg{KmpKrok}(I,x)$.
\::Pokud $I = J$, ohlásíme výskyt.
\endalgo
Hotový algoritmus mù¾eme zapsat následovnì:
-\s{Konstrukce zpìtných hran:}
-\algo
+\algo{KmpKonstrukce}
+\algin Jehla~$\iota$ délky~$J$.
\:$Z[0] \= ?$, $Z[1] \= 0$.
\:$I \= 0$.
\:Pro $K = 2, \ldots, J-1$:
-\::$I \= \<Krok>(I, \iota[K])$.
+\::$I \= \alg{KmpKrok}(I, \iota[K])$.
\::$Z[K] \= I$.
+\algout Pole zpìtných hran~$Z$.
\endalgo
-A~jsme hotovi výsledky shrnout do následující vìty:
+\>Výsledky mù¾eme shrnout do následující vìty:
\s{Vìta:} Algoritmus KMP najde v¹echny výskyty v~èase $O(J+S)$.
\>Celý algoritmus pro zpracování sena automatem pak bude vypadat takto:
-\s{Krok($I$, $x$):} \cmt{Jeden krok automatu: jsme ve stavu~$I$, pøeèetli jsme znak~$x$.}
-\algo
+\proc{AcKrok} \cmt{Jeden krok automatu}
+\algin Jsme ve~stavu~$I$, pøeèetli jsme znak~$x$.
\:Dokud $\<Dopøedu>(I, x) = \emptyset~\&~I \ne \<koøen>$: $I \= \<Zpìt>(I)$.
\:Pokud $\<Dopøedu>(I, x) \ne \emptyset$: $I \= \<Dopøedu>(I,x)$.
-\:Vrátíme nový stav~$I$.
+\algout Nový stav~$I$.
\endalgo
-\s{Hledej($\sigma$):} \cmt{Spu¹tìní automatu na øetìzec~$\sigma$.}
-\algo
+\algo{AcHledej} \cmt{Spu¹tìní automatu na daný øetìzec}
+\algin Seno~$\sigma$, zkonstruovaný automat.
\:$I \= \<koøen>$.
\:Pro znaky $x\in\sigma$ postupnì provádíme:
-\::$I \= \<Krok>(I, x)$.
+\::$I \= \alg{AcKrok}(I, x)$.
\::$K \= I$.
\::Dokud $K \neq \emptyset$:
\:::Je-li $\<Slovo>(K) \neq \emptyset$:
musí vést zkratka z~$K$ také do~$Q$. Pokud v~$Q$ ¾ádné slovo neskonèí, musí
zkratka z~$K$ vést do tého¾ vrcholu, jako zkratka z~$Q$.
-\s{Algoritmus: Konstrukce automatu}
-\algo
+\algo{AcKonstrukce}
+\algin Slova $\iota_1,\ldots,\iota_N$.
\:Zalo¾íme prázdný strom, $R \=$ jeho koøen.
-\:Vlo¾íme do~stromu slova $\iota_1 \dots \iota_n$, nastavíme $\<Slovo>$ ve~v¹ech stavech.
+\:Vlo¾íme do~stromu slova $\iota_1 \dots \iota_N$, nastavíme $\<Slovo>$ ve~v¹ech stavech.
\:$\<Zpìt>(R) \= \emptyset$, $\<Zkratka>(R) \= \emptyset$.
\:Zalo¾íme frontu $F$ a~vlo¾íme do~ní syny koøene.
\:Pro v¹echny syny~$K$ koøene: $\<Zpìt>(K) \= R$, $\<Zkratka>(K) \= \emptyset$.
\:Dokud $F \neq \emptyset$:
\::Vybereme $I$ z~fronty $F$.
\::Pro v¹echny syny $K$ vrcholu $I$:
-\:::$Q \= \<Krok>(\<Zpìt>(I), \hbox{písmeno na~hranì $IK$})$.
+\:::$Q \= \alg{AcKrok}(\<Zpìt>(I), \hbox{písmeno na~hranì $IK$})$.
\:::$\<Zpìt>(K) \= Q$.
\:::Pokud $\<Slovo>(Q) \neq \emptyset$: $\<Zkratka>(K) \= Q$.
\:::Jinak $\<Zkratka>(K) \= \<Zkratka>(Q)$.
\:::Vlo¾íme $K$ do~fronty $F$.
+\algout Strom, pole \<Slovo>, \<Zpìt> a \<Zkratka>.
\endalgo
Jeliko¾ tento algoritmus pouze napøeskáèku hledá v¹echny jehly, musí být jeho
Celý algoritmus pak bude vypadat následovnì:
-\algo
+\algo{RabinKarp}
+\algin Jehla $\iota$ délky~$J$, seno~$\sigma$ délky~$S$.
\:$X \= H(\iota)$. \cmt{he¹ jehly}
\:$Y \= H(\sigma[{}:J])$. \cmt{he¹ první pozice okénka}
\:Zvolíme~$P$ a~$N$ a pøedpoèítáme $P^J \bmod N$.
nalezených výskytù. Pokud nám bude staèit najít první výskyt a zvolíme $N > SJ$,
algoritmus pobì¾í v~prùmìrném èase $\O(S)$.
+\exercises
-%% Cvièení: velké abecedy
+\ex{Rozmyslete si, jak algoritmy z~této kapitoly upravit, aby si poradily
+s~velkými abecedami.}
+
+\endexercises
\bye