Suponha que recebamos uma coleção de strings, S 1 , ... , S n . Gostaria de saber se alguma dessas strings é uma substring de qualquer outra string da coleção. Em outras palavras, eu gostaria de um algoritmo para a seguinte tarefa:
Entrada:
Saída: tal que S i é uma subsequência de S j e i ≠ j , ou nenhum, se não, tais i , j existem
Existe um algoritmo eficiente para isso?
Se substituirmos "substring" por "prefix", existe um algoritmo eficiente (classifique as strings, faça uma varredura linear para comparar as strings adjacentes; a classificação garantirá que as substrings sejam adjacentes). Mas parece mais desafiador testar se uma string é uma substring de outra string. Um algoritmo ingênuo é iterar sobre todos os pares , mas isso requer Θ ( n 2 ) testes de substring. Existe um algoritmo mais eficiente?
Acho que poderíamos chamar isso de "teste de substring de todos os pares", ou algo assim.
Meu objetivo final é remover a coleção para que nenhuma string seja uma substring de qualquer outra, removendo cada uma que é uma substring de outra coisa na coleção.
Respostas:
Você pode construir uma árvore de sufixos em tempo linear e verificar se há um nó interno que corresponde a uma cadeia completa (tempo constante por nó).
Mais detalhadamente, suponha que recebamos as strings .s1,…,sn∈Σ∗
Crie uma árvore de sufixos (generalizada) de com n marcadores de terminal distintos em pares $ 1 , … , $ n ∉ Σ .s1$1,s2$2,…,sn$n n $1,…,$n∉Σ
Usando o algoritmo de Ukkonen , isso pode ser feito em tempo linear; linear na soma de todos os comprimentos de string.
Supondo que você rotule as folhas com se elas representam o sufixo s i [ j . . | s i | ] de s i , atravesse a árvore e encontre as n folhas rotuladas ( i , 0 ) , ou seja, as folhas que correspondem às seqüências completas.(i,j) si[j..|si|] si n (i,0)
Isso leva tempo linear no tamanho da árvore, que é linear no tamanho da entrada.
Isso novamente leva tempo linear.
Os marcadores terminais distintos não são realmente necessários; uma única usada para finalizar todas as seqüências é suficiente, desde que você permita vários rótulos por folha.
fonte