Algoritmo KMP para busca de substring

Livro de Sedgewick e Wayne: parte da sec.5.3, p.758.  Website do livro: resumo sec.5.3, slides.  Código fonte, documentação, e dados de teste de todos os programas do livro: veja algs4.cs.​princeton.edu​/code/.

Esta página discute o algoritmo descoberto por Knuth, Morris e Pratt para o problema da busca de substring.  Esse algoritmo introduz o conceito de autômato de estados, que é fundamental em várias áreas da Computação.  A página termina com uma breve indicação de outros algoritmos para o problema.

Destaques:

Pré-requisitos:

Ideia básica do algoritmo

Exercícios 1

  1. Quais são os invariantes do método search() do KMP?

Autômato de estados determinístico (DFA)

Construção do DFA

Exercícios 2

  1. Importante.  Escreva um algoritmo do tipo força bruta que receba pat e o alfabeto do texto e construa a tabela dfa[][].  Comparar o resultado com o do método KMP() do livro.

Construção eficiente do DFA

Código completo do algoritmo KMP

Desempenho do KMP

Exercícios 3

  1. (SW 5.3.2)  Dê a tabela dfa[][] do algoritmo KMP para o padrão  A A A A A A A A A.  Faça um desenho do DFA.
  2. (SW 5.3.3)  Dê a tabela dfa[][] do algoritmo KMP para o padrão  A B R A C A D A B R A.  (Suponha que o alfabeto é  A B C D R .)  Faça um desenho do DFA.
  3. (SW 5.3.17)  Mostre o autômato dfa[][] do algoritmo KMP para o alfabeto  A B C  e os seguintes padrões:
    • A A A A A A B
    • A A C A A A B
    • A B A B A B A B
    • A B A A B A A A B A A A B
    • A B A A B C A B A A B C B
  4. (SW 5.3.8)  Acrescente à classe KMP um método count() que conte o número de ocorrências do padrão.  (Por exemplo, o padrão  abcab  ocorre duas vezes no texto  xxxabcabcabxxxx.)  Acrescente um método searchAll() que imprima todas as ocorrências.
  5. (SW 5.3.24.b) Todas as ocorrências. Acrescente à classe KMP um método findAll() que devolve um Iterable<Integer> que permita ao cliente iterar sobre os inícios de todas as ocorrêcias do padrão no texto.
  6. (SW 5.3.14)  Escreva uma versão da classe KMP que use vetores de caracteres em lugar do tipo String para representar o padrão e o texto.
  7. (SW 5.3.25a) Streaming. Acrescente à classe KMP um método search() que receba um fluxo de entrada do tipo In como argumento e procure pelo padrão pat no fluxo de entrada especificado. Não use variáveis de instância adicionais (em particular, não armazene qualquer trecho do texto na memória).
  8. (SW 5.3.26) Rotação cíclica. Escreva um programa que receba duas strings e decida se uma é rotação cíclica da outra. (Por exemplo, example é rotação cíclica de ampleex.)
  9. (SW 5.3.27) Repetições em série. Uma repetição em série de uma string-base b em uma string s é uma substring de s que tenha pelo menos duas cópias consecutivas (sem sobreposição) de b.  Implemente um algoritmo de tempo linear que receba strings b e s e devolva o índice do início da mais longa repetição em série de b em s.  Por exemplo, seu programa deve devolver 3 quando b é  abcab  e s é  abcabcababcababcabcab.
  10. (SW 5.3.37) KMP para texto aleatório. Escreva um cliente que receba inteiros M, NT e execute o seguinte experimento T vezes: Gere um padrão aleatório de comprimento M e um texto aleatório de comprimento N e conte o número de comparações entre caracteres executado por KMP ao procurar o padrão no texto.  Imprima a média das contagens dos T experimentos.

 


Qual algoritmo de busca de substring é melhor?

Exercícios 4

  1. (SW 5.3.4) M brancos consecutivos. Escreva um método eficiente que receba um texto txt e um inteiro M e devolva a posição da primeira ocorrência de M brancos consecutivos no texto. Se não há uma tal ocorrência, devolva txt.length().  Estime o número de comparações de caracteres que seu método faz no pior caso e para um txt típico.

Próximo passo?


Perguntas e respostas