Algoritmos de Strings. Héctor Navarro

Documentos relacionados
Tipos algebraicos y abstractos. Algoritmos y Estructuras de Datos I. Tipos algebraicos

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

Algorítmica y Complejidad. Tema 3 Ordenación.

Análisis y Diseño de Algoritmos Tablas de Hash

Procesadores de lenguaje Tema 6 La tabla de símbolos

7.1 Consideraciones. Considere la búsqueda de un libro en una biblioteca. Considere la búsqueda de un nombre en el directorio telefónico.

Tema 9. Algoritmos sobre listas. Programación Programación - Tema 9: Algoritmos sobre listas

Programación. Tema 8: Tablas Hash. Apuntes elaborados por: Eduardo Quevedo, Aaron Asencio y Raquel López Revisado por: Javier Miranda el????

324 MR Versión 1 Prueba Integral 1/3 Semana 10 Lapso

Clases e instancias. Algoritmos y Estructuras de Datos I. Clases e instancias. memoria dinámica.

Desde los programas más simples escritos en un lenguaje de programación suelen realizar tres tareas en forma secuencial.

DEFINICION. Ing. M.Sc. Fulbia Torres Asignatura: Estructuras de Datos Barquisimeto 2006

Problema - Sumando Digitos

No todos los LRs finitos se representan mejor con ERs. Observe el siguiente ejemplo:

LEX. Las definiciones y subrutinas son opcionales. El segundo %% es opcional pero el primer %% indica el comienzo de las reglas.

El programa que permite el manejo de la base de datos tiene la siguiente funcionalidad:

PHP: Lenguaje de programación

Curso de Programación 1

Conjuntos. Un conjunto es una colección de objetos. Si a es un objeto y R es un conjunto entonces por. a R. se entiende que a pertenece a R.

Árboles de sufijos. Algoritmia para problemas difíciles Elvira Mayordomo

Estructuras de Datos Declaraciones Tipos de Datos

Variables. Una variable no es más que un nombre simbólico que identifica una dirección de memoria: vs.

Notación Asintótica 2

Universidad de Valladolid. Departamento de informática. Campus de Segovia. Estructura de datos Tema 4: Ordenación. Prof. Montserrat Serrano Montero

XQuery. Un lenguaje de consulta para XML.

FUNCIONES EN EXCEL III

Expresiones regulares y distancia de edición.

Tabla de Símbolos. Programación II Margarita Álvarez

1.1. Los números reales

REFERENCIA DEL LENGUAJE

Examen escrito de Programación 1. Jueves 5 de febrero de Problema 1 o (3.5 puntos)

ORDENAMIENTO Y BÚSQUEDA EN ARREGLOS

Programación. Test Autoevaluación Tema 3

Titulación: Ingeniero Técnico en Informática de Gestión Curso: 2º

Estructuras de Datos. La pila es un objeto dinámico en constante cambio.

Pontificia Universidad Javeriana Departamento de Ingeniería de Sistemas Estructuras de Datos Proyecto del curso,

Tema Árboles generales. 9.2 Árboles binarios 9.3 Árboles de búsqueda

Métodos de Ordenamiento. Unidad VI: Estructura de datos

FORMATO CONDICIONAL EN EXCEL

TEMA 7: Ficheros. TEMA 7: Ficheros Concepto de fichero

Diagramas de secuencia

Sistemas Operativos Practica 1: procesos y concurrencia.

Todo programa en 'C' consta de una o más funciones, una de las cuales se llama main.

Relaciones. Estructuras Discretas. Relaciones. Relaciones en un Conjunto. Propiedades de Relaciones en A Reflexividad

Máquinas Secuenciales, Autómatas y Lenguajes. Tema 3.1: Autómatas Finitos Deterministas

Algoritmos de Ordenación

Programación de Computadores 4 Iteraciones y Decisiones. Prof. Javier Cañas. Universidad Técnica Federico Santa María Departamento de Informática

MODELOS DE COMPUTACION I Preguntas Tipo Test. 1. El lema de bombeo puede usarse para demostrar que un lenguaje determinado es regular.

Unidad Nº V Listas Enlazadas

Elementos de un programa en C

PROGRAMACIÓN EN C#.NET Módulo 4.- Arreglos y cadenas. Ing. Bruno López Takeyas

Complejidad computacional (Análisis de Algoritmos)

Ciclos. Recordando Estructuras de Control Básicas: SELECCIÓN (condición) SECUENCIAL

INSTRUMENTACIÓN N AVANZADA. ARRAYS EN LABVIEW Relacionando Datos Arrays y Clusters

ALGORITMOS DE ORDENAMIENTO COUNTING SORT CHRISTIAN ESTEBAN ALDANA ROZO BRAYAN STIF FORERO CRUZ GIOVANNY GUZMÁN CÉSPEDES JORGE MEJIA

ELO320 Estructuras de Datos y Algoritmos. Arboles Binarios. Tomás Arredondo Vidal

Análisis y Diseño de Algoritmos

Estructuras de datos. Estructuras de datos

Algoritmos para determinar Caminos Mínimos en Grafos

Algoritmo para Calcular Logaritmos

Variables. Una variable no es más que un nombre simbólico que identifica una dirección de memoria: vs.

Alonso Ramirez Manzanares Computación y Algoritmos 03.05

TIPO DE DATO ABSTRACTO (TDA)

Solución al Examen de Prácticas de Programación (Ingeniería Informática)

Algoritmos. Medios de expresión de un algoritmo. Diagrama de flujo

Fundamentos de programación

= RETURN =3 7-. ELSE K

Estructuras de Control

UNIDAD 9. DATOS COMPLEJOS PILAS

Sistemas de Información II Tema 8. Estructuras de datos en memoria secundaria

Ficheros conceptos. Manejo de ficheros en C. Apertura del fichero Función fopen: nombre del fichero. Apertura del fichero Función fopen

Capítulo 2: Inducción y recursión Clase 2: El principio de Inducción Fuerte

La clase String

fundamentos de programación (unidad 4) programación estructurada en Java

EJERCICIOS del TEMA 3: Lenguajes independientes del contexto

IN Guía de Problemas Resueltos de Geometría de Programación Lineal v1.0

RADIO =? R AREA = : πr 2 < CIRC = : 2 πr

Tema 3. Análisis de costes

CONCEPTOS BASICOS DEL LENGUAJE JAVA

Tema 2. El lenguaje JAVA

Teoría de grafos y optimización en redes

Árboles Filogenéticos. BT7412, CC5702 Bioinformática Diego Arroyuelo. 2 de noviembre de 2010

PROGRAMACION ORIENTADA A OBJETOS Ingenieria Informática Final Febrero 2006/07

Este material es de uso exclusivo para estudio, los textos fueron tomados textualmente de varios libros por lo que está prohibida su impresión y

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Conceptos básicos de bases de datos

Arrays unidimensionales. Dim.Option Base. Erase. Ejemplos en Visual Basic (CU00311A)

Tecnólogo Informático- Estructuras de Datos y Algoritmos- 2009

Tema 2. Memoria Dinámica. 2.1 Datos estáticos y dinámicos

Uso avanzado de punteros

Examen Principios de Programación Febrero 2012

Enunciados de los problemas (1)

Definición de Memoria

PRÁCTICA No. 13 ÁRBOL BINARIO DE BÚSQUEDA

TEMA 4. ESTRUCTURAS DE CONTROL

Introducción Supongamos un subconjunto de n elementos X = {e 1,,e n de un conjunto referencial Y, X Y. Dentro de Y se define una relación de orden tot

Agradecimientos. Nota de los autores. 1 Problemas, algoritmos y programas 1

Transcripción:

lgoritmos de Strings Héctor Navarro

Substrings Dado un string T (posiblemente muy grande) y un patrón P (de tamaño menor), encontrar la primera (o todas) las apariciones de P en T Solución trivial de (NM) N es el tamaño de T M es el tamaño de P

Substrings for (i=0; T[i]!= '\0'; i++) { } for (j=0; T[i+j]!= '\0' && P[j]!= '\0' && T[i+j]==P[j]; j++) ; if (P[j] == '\0') // found a match

Substrings Peor caso: T= aaaa a P= aaa ab Normalmente no se comporta tan mal ya que se descartan rápidamente en las primeras iteraciones

Substrings P = nano i 0 1 2 3 4 5 6 7 8 9 10 11 T b a n a n a n o b a n o i=0 X i=1 X i=2 n a n X i=3 X i=4 n a n o i=5 X i=6 n X i=7 X i=8 X i=9 n X i=10 X

utómata Es posible construir un autómata en base al patrón para hacer búsquedas n a n o j=0 j=1 j=2 j=3 j=4 En cada estado existen dos posibilidades: La letra actual coincide con la letra reconocida en ese estado: avanzar al siguiente estado y letra

utómata Es posible construir un autómata en base al patrón para hacer búsquedas n a n o j=0 j=1 j=2 j=3 j=4 En cada estado existen dos posibilidades: La letra actual no coincide con la letra reconocida en ese estado: avanzar al siguiente estado, no avanzar la letra

utómata Es posible construir un autómata en base al patrón para hacer búsquedas n a n o j=0 j=1 j=2 j=3 j=4 En el estado 0 siempre se avanza de letra

utómata Es posible construir un autómata en base al patrón para hacer búsquedas n a n o j=0 j=1 j=2 j=3 j=4 B N N N B N

utómata Es posible construir un autómata en base al patrón para hacer búsquedas n a n a j=0 j=1 j=2 j=3 j=4 N N N

KMP Knuth Morris Pratt Convertir el autómata en código j = 0; for (i = 0; i < n; i++) while(1) { if (T[i] == P[j]) { // matches? j++; // yes, move on to next state if (j == m) { // match! j = reset[j];// ya reconocimos algunos caracteres de P } break; } else if (j == 0) break; // no match (j==0), next T else j = reset[j]; // no match (j!=0), // shorter partial match }

KMP Knuth Morris Pratt ecorrer este autómata es de (N), ya que en cada iteración se inspecciona un solo carácter de T El while más interno sólo se puede ejecutar en el peor caso una cantidad de veces igual al estado en el que estemos actualmente (M estados), pero una vez que se hace esto, regresamos al estado 0 (costo amortizado)

KMP Knuth Morris Pratt Falta ver cómo se realiza la construcción del arreglo de transiciones de estados (reset)

eset reset[i] indica el estado al que hay que saltar una vez que ya se han reconocido i caracteres y hay una falla Por ejemplo, si P= aabaab y ya hemos reconocido 5 caracteres (aabaa), dónde debemos saltar?

eset Por ejemplo, si P= aabaab y ya hemos reconocido 5 caracteres (aabaa), dónde debemos saltar? El sufijo más largo de esos 5 caracteres que también es prefijo de P, sería aa aabaa aabaab

eset Supongamos P=B reset[0]=0 (aunque nunca se usa) reset[1]=0 Para reset[2] basta ver que P[2-1]=P[0], por lo tanto, si hay una falla en este punto debemos regresar al estado 1 (reset[2]=1)

eset Supongamos P=B Para reset[3] basta ver que P[3-1]=P[1], por lo tanto, si hay una falla en este punto debemos regresar al estado 2 (reset[3]=2) Para reset[4], P[4-1]!=P[2], esto significa que cuando estamos en el estado 4 y no viene una B, debemos regresar al estado indicado por reset[3] (estado 2) Pero como P[3]!=P[1], este estado tampoco sirve. El único estado que sirve es el estado 0

eset int i = 0, j = -1; reset[0] = -1; while(i<m){ while(j>=0 && P[i]!=P[j]) j = reset[j]; i++; j++; reset[i] = j; }

eset En cada iteración se avanza un caracter de P El while más interno se hace a lo sumo tantas veces como caracteres hayamos procesado hasta ahora. Pero una vez que esto se hace, regresamos a j=0, por lo que el while interno se hará más corto en las siguientes iteraciones Esta parte del algoritmo es entonces de (M)

eset tros ejemplos P=B

eset tros ejemplos P=BCBC

eset tros ejemplos P=BXYZXYZ

KMP Finalmente KMP requiere de (M)+(N)=(N+M) N tamaño del string en donde queremos hacer la búsqueda M tamaño del substring que estamos buscando

Boyer-Moore También está basado en un autómata para hacer eficiente la búsqueda En lugar de hacer matching en los primeros caracteres del patrón de búsqueda, se hace en los últimos, acelerando el procesamiento Mientras el patrón sea más grande, el algoritmo se ejecutará más rápidamente

Tries Un Trie es un árbol en donde se almacenan palabras para encontrarlas rápidamente Supongamos que las palabras están formadas por caracteres de un alfabeto con cardinalidad n Cada nodo del Trie puede tener n hijos

Tries Por ejemplo, si las palabras pueden estar formadas por letras mayúsculas en inglés (26 caracteres), un nodo se ve como esto: B C D Y Z struct NodoTrie{ NodoTrie * hijo[26]; bool espalabra; };

Tries Insertar CS C S El atributo espalabra indica si en ese nodo termina una palabra

Tries Insertar C C S El atributo espalabra indica si en ese nodo termina una palabra

Tries Insertar DE C D E S El atributo espalabra indica si en ese nodo termina una palabra

Tries Insertar DED C D E S D El atributo espalabra indica si en ese nodo termina una palabra

Tries Búsqueda Seguir los enlaces dependiendo del valor de la letra actual Si un enlace es nil, la palabra no está en el Trie Si al terminar la palabra llegamos a un nodo con espalabra en falso, la palabra no está en el Trie Si al terminar la palabra llegamos a un nodo con espalabra en true, la palabra está en el Trie

Tries Buscar C C D E S D

Tries Buscar C C D E S D

Tries Buscar C C D E S D

Tries Buscar C C D E S D El apuntador es nil

Tries Buscar C C D E S D

Tries Buscar C C D E S D

Tries Buscar C C D E S D El apuntador no nil pero espalabra es falso

Tries bool buscar(char *w, Trie * T){ if(*w==null) return T->esPalabra; if(t->hijo[*w- ]==NULL) return false; return buscar(w+1, T->hijo[*w- ]); }

Trie de Sufijos Sirve para almacenar todos los sufijos de varios strings con el fin de poder recuperarlos rápidamente Con un Trie podemos rápidamente saber si una palabra está almacenada Con un Suffix Trie podemos rápidamente saber si algún substring está almacenado

Trie de Sufijos Supongamos la palabra CS Los posibles sufijos son: CS S S

Trie de Sufijos Si queremos agregar una palabra a un Suffix Trie, agregamos cada uno de sus sufijos (es posible que ya exista) Por ejemplo, supongamos las palabras CS, C, S, SP

Trie de Sufijos CS: CS,S,S, C S S S

Trie de Sufijos C: C,,,, C S S S

Trie de Sufijos S: S, S,, C S S S

Trie de Sufijos SP: SP, P, P, C P S P S S P

Trie de Sufijos hora podemos buscar cualquier substring de cualquier palabra del diccionario muy fácilmente ecordemos que el Trie permite reconocer prefijos del string Como almacenamos los sufijos de los strings, podemos reconocer cualquier prefijo de cualquier sufijo Un substring es justamente eso, un prefijo de un sufijo

Trie de Sufijos C, CS, SP, S. Buscar el substr S C P S P S S P

Trie de Sufijos C, CS, SP, S. Buscar el substr C P S P S S P

Trie de Sufijos C, CS, SP, S. Buscar el substr C P S P S S P

Árbol de Sufijos Sirve para almacenar eficientemente todos los sufijos de un solo string Usaremos un carácter especial para marcar el final del string ($), cuyo código SCII sea menor que el del resto de los caracteres del string El sufijo vacío debe estar en el suffix tree

Árbol de Sufijos Palabra: GTGC$ Sufijos: i Sufijo 0 GTGC$ 1 TGC$ 2 TGC$ 3 GC$ 4 GC$ 5 C$ 6 C$ 7 $ 8 $

Árbol de Sufijos i En cada nodo hoja del suffix tree se almacena el índice del sufijo que se encuentra ahí Sufijo 0 GTGC$ 1 TGC$ 2 TGC$ 3 GC$ 4 GC$ 5 C$ 6 C$ 7 $ 8 $ 7 5 $ 3 1 $ 8 6 2 4 0

Árbol de Sufijos Hay muchos substrings que se repiten (vértices repetidos) Un suffix tree se puede crear a partir de un suffix trie uniendo los nodos consecutivos que tienen un solo hijo

Árbol de Sufijos CS S C S 3 $ 4 $ 0 2 S 1

plicaciones del Suffix Tree Substring en (m+occ): m es el tamaño del patrón de búsqueda y occ es el número de ocurrencias del patrón en T 8 7 $ 6 2 4 5 3 1 0 Buscar el patrón

plicaciones del Suffix Tree Encontrar el substring más largo repetido en (n) 8 7 $ 6 2 4 5 3 1 0

plicaciones del Suffix Tree String común más largo en (N): construir el suffix tree de ambos strings en interceptarlos Ejemplo: SP vs TP

rreglo de Sufijos La construcción del suffix tree es muy compleja El suffix array tiene funcionalidades parecidas al suffix tree pero es más fácil de construir y de usar

rreglo de Sufijos Un arreglo de sufijos es un arreglo de enteros que almacena una permutación de los índices de los sufijos ordenados Por ejemplo, con T= GTGC$, n=9 El arreglo de sufijos asociado sería {8,7,5,3,1,6,4,0,2}

rreglo de Sufijos i Sufijo 0 GTGC$ 1 TGC$ 2 TGC$ 3 GC$ 4 GC$ 5 C$ 6 C$ 7 $ 8 $ rdenar i sa[i] Sufijo 0 8 $ 1 7 $ 2 5 C$ 3 3 GC$ 4 1 TGC$ 5 6 C$ 6 4 GC$ 7 0 GTGC$ 8 2 TGC$ El arreglo de sufijos asociado sería {8,7,5,3,1,6,4,0,2}

rreglo de Sufijos Si hacemos un recorrido en preorden del suffix tree obtenemos el suffix array 8 7 $ 6 2 4 5 3 1 0 {8,7,5,3,1,6,4,0,2}

rreglo de Sufijos Un nodo interno del suffix tree corresponde a un rango en el suffix array 8 7 $ 6 2 4 5 3 1 0 {8,7,5,3,1,6,4,0,2} {8,7,5,3,1,6,4,0,2}

rreglo de Sufijos Un nodo hoja del suffix tree corresponde a una entrada simple del suffix array 8 7 $ 6 2 4 5 3 1 0

rreglo de Sufijos Primera implementación char T[MX_N]; int S[MX_N], i, n; bool cmp(int a, int b){ return strcmp(t+a,t+b)<0; } n = strlen(t); for(int i=0; i<n; i++) S[i] = i; sort(s, S+n, cmp);

rreglo de Sufijos En tiempo requiere (N 2 log N) Esto puede mejorarse ordenando los sufijos caracter por caracter (usando un ordenamiento lineal basado en radix-sort) (N log N) Duplicar en cada paso el tamaño del sub string a comparar

rreglo de Sufijos GTGC$ (0) TGC$ (1) TGC$ (2) GC$ (3) GC$ (4) C$ (5) C$ (6) $ (7) $ (8) rdenar según el primer caracter $ (8) TGC$ (1) GC$ (3) C$ (5) $ (7) C$ (6) GTGC$ (0) TGC$ (2) GC$ (4)

rreglo de Sufijos $ (8) TGC$ (1) GC$ (3) C$ (5) $ (7) C$ (6) GTGC$ (0) TGC$ (2) GC$ (4) rdenar según dos primeros caracteres $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2)

rreglo de Sufijos $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2) rdenar según 4 primeros caracteres $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2)

rreglo de Sufijos $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2) rdenar según 8 primeros caracteres $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2)

rreglo de Sufijos Búsqueda de substring: hacer búsqueda binaria $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2) Buscar: GC li = 0 ls = 8 m = 4 T[S[m]] = TGC$

rreglo de Sufijos Búsqueda de substring: hacer búsqueda binaria $ (8) $ (7) C$ (5) GC$ (3) TGC$ (1) C$ (6) GC$ (4) GTGC$ (0) TGC$ (2) Buscar: GC li = 4 ls = 8 m = 6 T[S[m]] = GC$

rreglo de Sufijos Contar apariciones de un substring: hacer búsqueda binaria lower bound y upper bound para buscar en donde está Palabra: CLBL Contar apariciones de: L $ $ BL$ L$ LBL$ BL$ CLBL$ L$ LBL$

rreglo de Sufijos Contar apariciones de un substring: hacer búsqueda binaria lower bound y upper bound para buscar en donde está Palabra: CLBL Contar apariciones de: L $ $ BL$ L$ LBL$ BL$ CLBL$ L$ LBL$

rreglo de Sufijos Longest Common Prefix (LCP): el prefijo común más largo entre pares consecutivos de sufijos lcp[0] = 0 De ahí en adelante lcp[i] almacena el prefijo común más largo entre el s[i] y s[i-1] lgoritmo trivial de (N 2 ) Puede hacerse en (N)

rreglo de Sufijos i sa[i] Sufijo lcp[i] 0 8 $ 0 1 7 $ 0 2 5 C$ 1 3 3 GC$ 1 4 1 TGC$ 1 5 6 C$ 0 6 4 GC$ 0 7 0 GTGC$ 2 8 2 TGC$ 0

rreglo de Sufijos Un grupo de elementos consecutivos con el mismo lcp (mayor a cero) equivalen a un nodo interno del suffix tree 8 7 $ 6 2 4 5 3 1 0

Substring repetido más largo Supongamos el lcp siguiente: rreglo de Sufijos i lcp[i] 0 0 1 0 2 0 3 3 4 3 5 2 6 0 7 1 8 1 9 1 10 0

Substring que más se repite i lcp[i] 0 0 1 0 2 0 3 3 4 3 5 2 6 0 7 1 8 1 9 1 10 0 rreglo de Sufijos