Definitions and trie

This commit is contained in:
Antti H S Laaksonen 2017-01-22 13:15:41 +02:00
parent 0203944cc2
commit e03e9906a8
1 changed files with 119 additions and 119 deletions

View File

@ -1,108 +1,107 @@
\chapter{String algorithms} \chapter{String algorithms}
\index{merkkijono@merkkijono} \index{string}
\index{aakkosto@aakkosto} \index{alphabet}
Merkkijonon $s$ merkit ovat $s[1],s[2],\ldots,s[n]$, A string $s$ of length $n$
missä $n$ on merkkijonon pituus. is a sequence of characters
$s[1],s[2],\ldots,s[n]$.
\key{Aakkosto} sisältää ne merkit, An \key{alphabet} is a set of characters
joita merkkijonossa voi esiintyä. that may appear in strings.
Esimerkiksi aakkosto $\{\texttt{A},\texttt{B},\ldots,\texttt{Z}\}$ For example, the alphabet
sisältää englannin kielen suuret kirjaimet. $\{\texttt{A},\texttt{B},\ldots,\texttt{Z}\}$
consists of the capital letters of English.
\index{osajono@osajono} \index{substring}
\key{Osajono} A \key{substring} consists of consecutive
sisältää merkkijonon merkit characters in a string.
yhtenäiseltä väliltä. The number of substrings in a string is $n(n+1)/2$.
Merkkijonon osa\-jonojen määrä on $n(n+1)/2$. For example, \texttt{ORITH} is a substring
Esimerkiksi merkkijonon \texttt{ALGORITMI} in \texttt{ALGORITHM}, and it corresponds
yksi osajono on \texttt{ORITM}, to \texttt{ALG\underline{ORITH}M}.
joka muodostuu valitsemalla välin \texttt{ALG\underline{ORITM}I}.
\index{alijono@alijono} \index{subsequence}
\key{Alijono} A \key{subsequence} is a subset of characters
on osajoukko merkkijonon merkeistä. in a string in their original order.
Merkkijonon alijonojen määrä on $2^n-1$. The number of subsequences in a string is $2^n-1$.
Esimerkiksi merkkijonon \texttt{ALGORITMI} For example, \texttt{LGRHM} is a subsequece
yksi alijono on \texttt{LGRMI}, joka muodostuu in \texttt{ALGORITHM}, and it corresponds
valitsemalla merkit \texttt{A\underline{LG}O\underline{R}IT\underline{MI}}. to \texttt{A\underline{LG}O\underline{R}IT\underline{HM}}.
\index{alkuosa@alkuosa} \index{prefix}
\index{loppuosa@loppuosa} \index{suffix}
\index{prefiksi@prefiksi}
\index{suffiksi@suffiksi}
\key{Alkuosa} on merkkijonon A \key{prefix} is a subtring that contains the first
alusta alkava osajono, character of a string,
ja \key{loppuosa} on merkkijonon and a \key{suffix} is a substring that contains the last character.
loppuun päättyvä osajono. For example, the prefixes of
Esimerkiksi merkkijonon \texttt{KISSA} \texttt{STORY} are \texttt{S}, \texttt{ST},
alkuosat ovat \texttt{K}, \texttt{KI}, \texttt{STO}, \texttt{STOR} and \texttt{STORY},
\texttt{KIS}, \texttt{KISS} ja \texttt{KISSA} and the suffixes are \texttt{Y}, \texttt{RY},
ja loppuosat ovat \texttt{A}, \texttt{SA}, \texttt{ORY}, \texttt{TORY} and \texttt{STORY}.
\texttt{SSA}, \texttt{ISSA} ja \texttt{KISSA}. A prefix or a suffix is \key{proper}
Alkuosa tai loppuosa on \key{aito}, if it is not the whole string.
jos se ei ole koko merkkijono.
\index{kierto@kierto} \index{rotation}
\key{Kierto} syntyy A \key{rotation} can be generated by moving
siirtämällä jokin alkuosa merkkijonon loppuun characters one by one from the beginning to the end
tai jokin loppuosa merkkijonon alkuun. in a string (or vice versa).
Esimerkiksi merkkijonon \texttt{APILA} For example, the rotations of \texttt{STORY} are
kierrot ovat \texttt{STORY},
\texttt{APILA}, \texttt{TORYS},
\texttt{PILAA}, \texttt{ORYST},
\texttt{ILAAP}, \texttt{RYSTO} and
\texttt{LAAPI} ja \texttt{YSTOR}.
\texttt{AAPIL}.
\index{jakso@jakso} \index{period}
\key{Jakso} on alkuosa, A \key{period} is a prefix of a string such that
jota toistamalla merkkijono muodostuu. we can construct the string by repeating the period.
Jakson viimeinen toistokerta voi olla osittainen The last repetition may be partial and contain
niin, että siinä on vain jakson alkuosa. only a prefix of the period.
Usein on kiinnostavaa selvittää, mikä on merkkijonon Often it is interesting to find the \key{shortest period}
\key{lyhin jakso}. of a string.
Esimerkiksi merkkijonon \texttt{ABCABCA} lyhin jakso on \texttt{ABC}. For example, the shortest period of
Tässä tapauksessa merkkijono syntyy toistamalla jaksoa ensin kahdesti kokonaan \texttt{ABCABCA} is \texttt{ABC}.
ja sitten kerran osittain. In this case, we first repeat the period twice
and then partially.
\key{Reuna} on \index{border}
merkkijono, joka on sekä
alkuosa että loppuosa.
Esimerkiksi merkkijonon \texttt{ABADABA}
reunat ovat \texttt{A}, \texttt{ABA} ja
\texttt{ABADABA}.
Usein halutaan etsiä \key{pisin reuna},
joka ei ole koko merkkijono.
\index{leksikografinen jxrjestys@leksikografinen järjestys} A \key{border} is a string that is both
a prefix and a suffix of a string.
For example, the borders for \texttt{ABADABA}
are \texttt{A}, \texttt{ABA} and \texttt{ABADABA}.
Often we want to find the \key{longest border}
that is not the whole string.
Merkkijonojen vertailussa käytössä on yleensä \index{lexicographical order}
\key{leksikografinen järjestys}, joka vastaa aakkosjärjestystä.
Siinä $x<y$, jos joko $x$ on $y$:n aito alkuosa
tai on olemassa kohta $k$ niin,
että $x[i]=y[i]$, kun $i<k$, ja $x[k]<y[k]$.
\section{Trie-rakenne} Usually we compare string using the \key{lexicographical order}
that corresponds to the alphabetical order.
It means that $x<y$ if either $x$ is a proper prefix of $y$,
or there is an index $k$ such that
$x[i]=y[i]$ when $i<k$ and $x[k]<y[k]$.
\index{trie@trie} \section{Trie structure}
\key{Trie} on puurakenne, \index{trie}
joka pitää yllä joukkoa merkkijonoja.
Merkkijonot tallennetaan puuhun
juuresta lähtevinä merkkien ketjuina.
Jos useammalla merkkijonolla on sama alkuosa,
niiden ketjun alkuosa on yhteinen.
Esimerkiksi joukkoa A \key{trie} is a tree structure that
$\{\texttt{APILA},\texttt{APINA},\texttt{SUU},\texttt{SUURI}\}$ maintains a set of strings.
vastaa seuraava trie: Strings are stored in a trie as chains
of characters that start at the root
of the tree.
If two strings have a common prefix,
they also share a chain in the tree.
For example, the following trie corresponds
to the set
$\{\texttt{CANAL},\texttt{CANDY},\texttt{THE},\texttt{THERE}\}$:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.9] \begin{tikzpicture}[scale=0.9]
@ -120,50 +119,51 @@ vastaa seuraava trie:
\node[draw, circle] (12) at (1.5,14.5) {$\phantom{1}$}; \node[draw, circle] (12) at (1.5,14.5) {$\phantom{1}$};
\node[draw, circle] (13) at (1.5,13) {*}; \node[draw, circle] (13) at (1.5,13) {*};
\path[draw,thick,->] (1) -- node[font=\small,label=\texttt{A}] {} (2); \path[draw,thick,->] (1) -- node[font=\small,label=\texttt{C}] {} (2);
\path[draw,thick,->] (1) -- node[font=\small,label=\texttt{S}] {} (3); \path[draw,thick,->] (1) -- node[font=\small,label=\texttt{T}] {} (3);
\path[draw,thick,->] (2) -- node[font=\small,label=left:\texttt{P}] {} (4); \path[draw,thick,->] (2) -- node[font=\small,label=left:\texttt{A}] {} (4);
\path[draw,thick,->] (4) -- node[font=\small,label=left:\texttt{I}] {} (5); \path[draw,thick,->] (4) -- node[font=\small,label=left:\texttt{N}] {} (5);
\path[draw,thick,->] (5) -- node[font=\small,label=left:\texttt{L}] {} (6); \path[draw,thick,->] (5) -- node[font=\small,label=left:\texttt{A}] {} (6);
\path[draw,thick,->] (5) -- node[font=\small,label=right:\texttt{N}] {} (7); \path[draw,thick,->] (5) -- node[font=\small,label=right:\texttt{D}] {} (7);
\path[draw,thick,->] (6) -- node[font=\small,label=left:\texttt{A}] {}(8); \path[draw,thick,->] (6) -- node[font=\small,label=left:\texttt{L}] {}(8);
\path[draw,thick,->] (7) -- node[font=\small,label=right:\texttt{A}] {} (9); \path[draw,thick,->] (7) -- node[font=\small,label=right:\texttt{Y}] {} (9);
\path[draw,thick,->] (3) -- node[font=\small,label=right:\texttt{U}] {} (10); \path[draw,thick,->] (3) -- node[font=\small,label=right:\texttt{H}] {} (10);
\path[draw,thick,->] (10) -- node[font=\small,label=right:\texttt{U}] {} (11); \path[draw,thick,->] (10) -- node[font=\small,label=right:\texttt{E}] {} (11);
\path[draw,thick,->] (11) -- node[font=\small,label=right:\texttt{R}] {} (12); \path[draw,thick,->] (11) -- node[font=\small,label=right:\texttt{R}] {} (12);
\path[draw,thick,->] (12) -- node[font=\small,label=right:\texttt{I}] {} (13); \path[draw,thick,->] (12) -- node[font=\small,label=right:\texttt{E}] {} (13);
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Merkki * solmussa tarkoittaa, The character * in a node means that
että jokin merkkijono päättyy kyseiseen solmuun. a string ends at the node.
Tämä merkki on tarpeen, This character is needed because a string
koska merkkijono voi olla toisen merkkijonon alkuosa, may be a prefix of another string.
kuten tässä puussa merkkijono \texttt{SUU} For example, in this trie, \texttt{THE}
on merkkijonon \texttt{SUURI} alkuosa. is a suffix of \texttt{THERE}.
Triessä merkkijonon lisääminen ja hakeminen Inserting and searching a string in a trie take $O(n)$ time
vievät aikaa $O(n)$, kun $n$ on merkkijonon pituus. where $n$ is the length of the string.
Molemmat operaatiot voi toteuttaa lähtemällä liikkeelle juuresta Both operations can be implemented by
ja kulkemalla alaspäin ketjua merkkien mukaisesti. starting at the root node and following the
Tarvittaessa puuhun lisätään uusia solmuja. chain of characters that appear in the string.
If needed, new nodes will be added to the trie.
Triestä on mahdollista etsiä Trie can be used for searching both strings
sekä merkkijonoja että merkkijonojen alkuosia. and prefixes of strings.
Lisäksi puun solmuissa voi pitää kirjaa, In addition, we can keep track of the number
monessako merkkijonossa on solmua vastaava alkuosa, of strings that have each prefix,
mikä lisää trien käyttömahdollisuuksia. that can be useful in some applications.
Trie on kätevää tallentaa taulukkona A trie can be stored as an array
\begin{lstlisting} \begin{lstlisting}
int t[N][A]; int t[N][A];
\end{lstlisting} \end{lstlisting}
missä $N$ on solmujen suurin mahdollinen määrä where $N$ is the maximum number of nodes
(eli tallennettavien merkkijonojen yhteispituus) (the total length of the string to be stored)
ja $A$ on aakkoston koko. and $A$ is the size of the alphabet.
Trien solmut numeroidaan $1,2,3,\ldots$ niin, The nodes of a trie are numbered
että juuren numero on 1, $1,2,3,\ldots$ so that the number of the root is 1,
ja taulukon kohta $\texttt{t}[s][c]$ kertoo, and $\texttt{t}[s][c]$ is the next node in chain
mihin solmuun solmusta $s$ pääsee merkillä $c$. from node $s$ using character $c$.
\section{Merkkijonohajautus} \section{Merkkijonohajautus}