Professional Documents
Culture Documents
Leopoldo Taravilse1
1 Facultad
Strings
TC 2014
1 / 51
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
2 / 51
String Matching
String Matching
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
3 / 51
String Matching
String Matching
Qu es String Matching?
Strings
TC 2014
4 / 51
String Matching
String Matching
Solucin Trivial
Strings
TC 2014
5 / 51
String Matching
String Matching
Solucin Trivial
Strings
TC 2014
5 / 51
String Matching
String Matching
Solucin Trivial
Strings
TC 2014
5 / 51
String Matching
Bordes
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
6 / 51
String Matching
Bordes
Bordes de un String
Definicin de borde
Un borde de un string S es un string B (|B| < |S|) que es a su vez
prefijo y sufijo de S.
Strings
TC 2014
7 / 51
String Matching
Bordes
Bordes de un String
Definicin de borde
Un borde de un string S es un string B (|B| < |S|) que es a su vez
prefijo y sufijo de S.
Por ejemplo, a y abra son bordes de abracadabra.
Strings
TC 2014
7 / 51
String Matching
Bordes
Deteccin de bordes
Strings
TC 2014
8 / 51
String Matching
Bordes
Deteccin de bordes
Strings
TC 2014
8 / 51
String Matching
Bordes
Deteccin de bordes
Strings
TC 2014
8 / 51
String Matching
Bordes
Deteccin de bordes
Strings
TC 2014
8 / 51
String Matching
Bordes
Deteccin de bordes
Lema 1
Si S 0 es borde de S y S 00 es borde de S 0 entonces S 00 es borde de S.
Al ser S 00 prefijo de S 0 y S 0 prefijo de S, entonces S 00 es prefijo de S, y
anlogamente es sufijo de S.
Strings
TC 2014
9 / 51
String Matching
Bordes
Deteccin de bordes
Lema 1
Si S 0 es borde de S y S 00 es borde de S 0 entonces S 00 es borde de S.
Al ser S 00 prefijo de S 0 y S 0 prefijo de S, entonces S 00 es prefijo de S, y
anlogamente es sufijo de S.
Lema 2
Si S 0 y S 00 son bordes de S y |S 00 | < |S 0 |, entonces S 00 es borde de S 0 .
Como S 00 es prefijo de S y S 0 tambin, entonces S 00 es prefijo de S 0 .
Anlogamente S 00 es sufijo de S 0 .
Strings
TC 2014
9 / 51
String Matching
Bordes
Deteccin de bordes
Lema 1
Si S 0 es borde de S y S 00 es borde de S 0 entonces S 00 es borde de S.
Al ser S 00 prefijo de S 0 y S 0 prefijo de S, entonces S 00 es prefijo de S, y
anlogamente es sufijo de S.
Lema 2
Si S 0 y S 00 son bordes de S y |S 00 | < |S 0 |, entonces S 00 es borde de S 0 .
Como S 00 es prefijo de S y S 0 tambin, entonces S 00 es prefijo de S 0 .
Anlogamente S 00 es sufijo de S 0 .
Lema 3
Si S 0 y S 00 son bordes de S y el mayor borde de S 0 es S 00 , entonces S 00
es el mayor borde de S de longitud menor a |S 0 |.
Leopoldo Taravilse (UBA)
Strings
TC 2014
9 / 51
String Matching
Bordes
Strings
TC 2014
10 / 51
String Matching
Bordes
Strings
TC 2014
10 / 51
String Matching
Bordes
Strings
TC 2014
10 / 51
String Matching
Bordes
Strings
TC 2014
11 / 51
String Matching
Bordes
Strings
TC 2014
11 / 51
String Matching
Bordes
1
2
i f ( st [ i ] == st [ j ] )
j ++;
bordes[ i ++] = j ;
Strings
TC 2014
12 / 51
String Matching
Bordes
j = bordes[ j 1];
Strings
TC 2014
13 / 51
String Matching
Knuth-Morris-Pratt
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
14 / 51
String Matching
Knuth-Morris-Pratt
String Matching
Strings
TC 2014
15 / 51
String Matching
Knuth-Morris-Pratt
String Matching
Strings
TC 2014
15 / 51
String Matching
Knuth-Morris-Pratt
String Matching
Strings
TC 2014
15 / 51
String Matching
Knuth-Morris-Pratt
Cdigo de KMP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string s, t ;
void fill_table ()
{
int pos = 2, cnd = 0;
kmp_table[0] = 1;
kmp_table[1] = 0;
while(pos<s. size () )
{
i f (s[pos1] == s[cnd] )
kmp_table[pos++] = ++cnd;
else i f (cnd>0)
cnd = kmp_table[cnd] ;
else
kmp_table[pos++] = 0;
}
}
Strings
TC 2014
16 / 51
String Matching
Knuth-Morris-Pratt
Cdigo de KMP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int kmp() {
fill_table () ;
int m=0, i =0;
while(m +i <t . size () ) {
i f (s[ i ] == t [m+i ] ) {
i f ( i==s. size ()1)
return m;
i ++;
}
else{
m = m +ikmp_table[ i ] ;
i f (kmp_table[ i]>1)
i = kmp_table[ i ] ;
else
i = 0;
}
}
return 1;
}
Leopoldo Taravilse (UBA)
Strings
TC 2014
17 / 51
String Matching
Knuth-Morris-Pratt
Strings
TC 2014
18 / 51
Tries
Tries
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
19 / 51
Tries
Tries
Qu es un Trie?
Definicin de Trie
Los tries sirven para representar diccionarios de palabras. Un trie es
un rbol de caracteres en el que cada camino de la raiz a un nodo final
(no necesariamente una hoja) es una palabra de dicho diccionario.
Strings
TC 2014
20 / 51
Tries
Tries
Qu es un Trie?
Definicin de Trie
Los tries sirven para representar diccionarios de palabras. Un trie es
un rbol de caracteres en el que cada camino de la raiz a un nodo final
(no necesariamente una hoja) es una palabra de dicho diccionario.
Veamos un ejemplo de un Trie con las palabras hola, holamundo,
mundo y mundial.
Strings
TC 2014
20 / 51
Tries
Tries
Ejemplo de un Trie
root
h
d
o
Leopoldo Taravilse (UBA)
Strings
TC 2014
21 / 51
Tries
Tries
1
2
3
4
5
6
7
8
9
10
11
12
13
struct trie {
map <char, int> sig ;
bool final ;
/ /puede ser map <int , int> si el alfabeto son enteros
};
trie t [MAXN] ;
int n;
void i n i t ()
{
n = 1;
t [0]. sig . clear () ;
t [0]. final = false ;
}
Strings
TC 2014
22 / 51
Tries
Tries
1
2
3
4
5
6
7
8
9
10
11
12
13
Strings
TC 2014
23 / 51
Tries
Tries
Ejemplo
Diseo de Camisetas
Dados dos equipos de rugby con n jugadores cada uno, quieren
compartir las camisetas (un jugador de cada equipo por cada
camiseta) de modo tal que cada camiseta tenga un prefijo comn
entre los apellidos de los dos jugadores que la usan (es vlido el
prefijo vaco), y entre todas las camisetas usen la mayor cantidad de
letras posibles.
Problema D - TAP 2012. Link a la prueba: http://goo.gl/ypdYS
Strings
TC 2014
24 / 51
Tries
Tries
Diseo de Camisetas
Strings
TC 2014
25 / 51
Tries
Tries
Diseo de Camisetas
Strings
TC 2014
25 / 51
Tries
Tries
Diseo de Camisetas
Strings
TC 2014
25 / 51
Tries
Tries
Problemas
http://goo.gl/gQOSG
http://goo.gl/KTVKd
Strings
TC 2014
26 / 51
Suffix Array
Suffix Array
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
27 / 51
Suffix Array
Suffix Array
Motivacin
Problema
Dado un string calcular la cantidad de substrings distintos que tiene
dicho string.
Strings
TC 2014
28 / 51
Suffix Array
Suffix Array
Motivacin
Problema
Dado un string calcular la cantidad de substrings distintos que tiene
dicho string.
Veremos a continuacin dos algoritmos que nos sirven para resolver
este problema eficientemente.
Strings
TC 2014
28 / 51
Suffix Array
Suffix Array
Sufijos de un string
Muchas veces puede interesarnos ordenar los sufijos de un string
lexicogrficamente.
Strings
TC 2014
29 / 51
Suffix Array
Suffix Array
Sufijos de un string
Muchas veces puede interesarnos ordenar los sufijos de un string
lexicogrficamente.
En principio un string de longitud n tiene n + 1 sufijos (contando el
string completo y el sufijo vaco), y la suma de la cantidad de
caracteres de todos esos sufijos es O(n2 ), por lo que tan slo leer
los sufijos para compararlos tomara una cantidad de tiempo
cuadrtica en la cantidad de caracteres del string.
Strings
TC 2014
29 / 51
Suffix Array
Suffix Array
Sufijos de un string
Muchas veces puede interesarnos ordenar los sufijos de un string
lexicogrficamente.
En principio un string de longitud n tiene n + 1 sufijos (contando el
string completo y el sufijo vaco), y la suma de la cantidad de
caracteres de todos esos sufijos es O(n2 ), por lo que tan slo leer
los sufijos para compararlos tomara una cantidad de tiempo
cuadrtica en la cantidad de caracteres del string.
Una forma de implementar Suffix Array en O(n2 ) es con un Trie.
Insertando todos los sufijos y luego recorriendo el trie en orden
lexicogrfico podemos listar los sufijos en dicho orden.
Strings
TC 2014
29 / 51
Suffix Array
Suffix Array
Suffix Array
Qu es un Suffix Array?
A veces queremos tener ordenados lexicogrficamente los sufijos de
un string. Un Suffix Array es un arreglo que tiene los ndices de las
posiciones del string donde empiezan los sufijos, ordenados
lexicogrficamente.
Strings
TC 2014
30 / 51
Suffix Array
Suffix Array
b r
6 10
a
3
c
7
a
4
d
8
a
1
b
5
r
9
a
0
Strings
TC 2014
31 / 51
Suffix Array
Suffix Array
Suffix Array
Al igual que con KMP, el algoritmo que calcula el Suffix Array
reutiliza informacin para ahorrar tiempo.
Strings
TC 2014
32 / 51
Suffix Array
Suffix Array
Suffix Array
Al igual que con KMP, el algoritmo que calcula el Suffix Array
reutiliza informacin para ahorrar tiempo.
Si sabemos que chau viene antes que hola, entonces sabemos
que chaupibe viene antes que holapepe y no necesitamos
comparar pibe con pepe.
Strings
TC 2014
32 / 51
Suffix Array
Suffix Array
Suffix Array
Al igual que con KMP, el algoritmo que calcula el Suffix Array
reutiliza informacin para ahorrar tiempo.
Si sabemos que chau viene antes que hola, entonces sabemos
que chaupibe viene antes que holapepe y no necesitamos
comparar pibe con pepe.
Para saber que chau viene antes que hola, no tuvimos que
comparar todo el string chau con el string hola, sino que slo
comparamos ch con ho, y para saber que ch viene antes que ho
comparamos c con h.
Strings
TC 2014
32 / 51
Suffix Array
Suffix Array
Suffix Array
Al igual que con KMP, el algoritmo que calcula el Suffix Array
reutiliza informacin para ahorrar tiempo.
Si sabemos que chau viene antes que hola, entonces sabemos
que chaupibe viene antes que holapepe y no necesitamos
comparar pibe con pepe.
Para saber que chau viene antes que hola, no tuvimos que
comparar todo el string chau con el string hola, sino que slo
comparamos ch con ho, y para saber que ch viene antes que ho
comparamos c con h.
La idea del Suffix Array pasa por ir comparando prefijos de los
sufijos de longitud 2t , e ir ordenando para cada t hasta que t sea
mayor o igual que la longitud del string.
Strings
TC 2014
32 / 51
Suffix Array
Suffix Array
string st ;
vector<int> sa[18];
vector<int> bucket[18];
int t , n;
void i n i t () {
n = st . size () ;
for ( int i =0;(1<< i )<2n; i ++){
sa[ i ] . resize(n) ;
bucket[ i ] . resize(n) ;
for ( int j =0;j <n; j ++)
sa[ i ] [ j ] = j ;
}
sort (sa[0].begin() ;sa[0].end() ,comp1) ;
initBuckets () ;
for ( t=0;(1<<t )<n; t++){
sort (sa[ t +1].begin() ;sa[ t +1].end() ;comp2) ;
sortBuckets() ;
}
}
Leopoldo Taravilse (UBA)
Strings
TC 2014
33 / 51
Suffix Array
Suffix Array
Strings
TC 2014
34 / 51
Suffix Array
Suffix Array
void initBuckets () {
bucket[0][sa[0][0]] = 0;
for ( int i =1;i <n; i ++)
i f ( st [sa[0][ i ] ] == st [sa[0][ i 1]])
bucket[0][sa[0][ i ] ] = bucket[0][sa[0][ i 1]];
else
bucket[0][sa[0][ i ] ] = i ;
}
void sortBuckets() {
bucket[ t +1][sa[ t +1][0]] = 0;
int d = (1<<t ) ;
for ( int i =1;i <n; i ++)
i f (bucket[ t ] [sa[ t +1][ i ] ] == bucket[ t ] [sa[ t +1][ i 1]]
&& sa[ t +1][ i ]+d < n && sa[ t +1][ i 1] < n
&& bucket[ t ] [sa[ t +1][ i ]+d] == bucket[ t ] [sa[ t +1][ i1]+d] )
bucket[ t +1][sa[ t +1][ i ] ] = bucket[ t +1][sa[ t +1][ i 1]];
else
bucket[ t +1][sa[ t +1][ i ] ] = i ;
}
Leopoldo Taravilse (UBA)
Strings
TC 2014
35 / 51
Suffix Array
Suffix Array
Strings
TC 2014
36 / 51
Suffix Array
Suffix Array
Strings
TC 2014
36 / 51
Suffix Array
Suffix Array
Strings
TC 2014
36 / 51
Suffix Array
Suffix Array
Strings
TC 2014
36 / 51
Suffix Array
Suffix Array
Strings
TC 2014
37 / 51
Suffix Array
Suffix Array
Strings
TC 2014
37 / 51
Suffix Array
Suffix Array
Strings
TC 2014
37 / 51
Suffix Array
Suffix Array
Strings
TC 2014
37 / 51
Suffix Array
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
38 / 51
Suffix Array
LCP
Strings
TC 2014
39 / 51
Suffix Array
LCP
Strings
TC 2014
39 / 51
Suffix Array
Ejemplo de LCP
SA
0
1
2
3
4
5
6
7
8
9
10
S = abracadabra
a
abra
abracadabra
acadabra
adabra
bra
bracadabra
cadabra
dabra
ra
racadabra
LCP
0
1
4
1
1
0
3
0
0
0
2
a
abra
a
a
bra
ra
Strings
TC 2014
40 / 51
Suffix Array
vector<int> lcp ;
void llenarLCP()
{
int n = st . size () ;
lcp . resize(n1);
int q=0, j ;
for ( int i =0;i <n; i ++)
i f (bucket[ t ] [ i ]!=0)
{
j = sa[ t ] [ bucket[ t ] [ i ]1];
while(q+max( i , j ) < n && st [ i+q] == st [ j+q] )
q++;
lcp [bucket[ t ] [ i ]1] = q;
i f (q>0)
q;
}
}
Strings
TC 2014
41 / 51
Suffix Array
Strings
TC 2014
42 / 51
Suffix Array
i f (q>0)
q;
Strings
TC 2014
43 / 51
Suffix Array
Strings
TC 2014
44 / 51
Suffix Array
Strings
TC 2014
45 / 51
Algoritmo de Manacher
Contenidos
1
String Matching
String Matching
Bordes
Knuth-Morris-Pratt
Tries
Tries
Suffix Array
Suffix Array
Longest Common Prefix
Strings
TC 2014
46 / 51
Algoritmo de Manacher
Qu es un palndromo
Definicin
Un palndromo es un string que se lee igual de atrs para adelante y
de adelante para atrs. Algunos ejemplos de palndromos son
Neuquen, Anitalavalatina o el apellido de un famoso ex presidente
argentino.
Strings
TC 2014
47 / 51
Algoritmo de Manacher
Problema
Un problema muy comn es el de buscar el palndromo ms largo que
es substring de un string dado. Este problema tiene una solucin lineal
y es con el algoritmo de Manacher.
Strings
TC 2014
48 / 51
Algoritmo de Manacher
Algoritmo de Manacher
Strings
TC 2014
49 / 51
Algoritmo de Manacher
Algoritmo de Manacher
Strings
TC 2014
49 / 51
Algoritmo de Manacher
Algoritmo de Manacher
Strings
TC 2014
49 / 51
Algoritmo de Manacher
Algoritmo de Manacher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Strings
TC 2014
50 / 51
Algoritmo de Manacher
Algoritmo de Manacher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Strings
TC 2014
50 / 51
Algoritmo de Manacher
Strings
TC 2014
51 / 51
Algoritmo de Manacher
Strings
TC 2014
51 / 51