Estou tentando usar árvores de sufixo para comparar seqüências de caracteres. Eu encontrei implementações / teoria para o maior problema de sub-string comum usando árvores de sufixo. No entanto, o que estou procurando é uma discussão sobre o problema relacionado - "todas as substrings comuns". Especificamente, tenho um problema no qual preciso primeiro encontrar a substring comum mais longa, depois encontrar a próxima substring comum mais longa que não inclua os índices lcs já encontrados e assim por diante até um comprimento mínimo. Esse problema é solucionável através da construção da árvore de sufixos generalizados (GST) apenas uma vez para as duas seqüências. Eu sei que isso pode ser resolvido através da construção repetida de um GST após cada iteração de localização e remoção do LCS. Mas, eu estou querendo saber se estou faltando um truque puro onde no GST é construído apenas uma vez.
10
Respostas:
Sim, árvores com sufixo podem ser usadas para encontrar todas as substrings comuns. Eu diria que, em vez disso, use uma matriz de sufixos, mas se você já tiver uma árvore de sufixos, a criação de uma matriz de sufixos a partir de uma árvore de sufixos leva tempo linear pelo DFS. Portanto, o restante da minha resposta assumirá que estamos trabalhando com uma matriz de sufixos.
Dado um texto , uma matriz de sufixos para S é uma matriz de números inteiros do intervalo 0 a n que especifica a ordem lexicográfica dos n + 1 sufixos da sequência S $S= s1 1, . . . , sn S 0 0 n n + 1 S
Queremos combinar a matriz de sufixos com , os prefixos comuns mais longos. Podemos construir a matriz de L C P s em tempo linear, como mencionado no artigo de Kasai et al . Matrizes de sufixo e suas matrizes lcp se alinham de maneira que, dado um índice na matriz lcp, digamos l c p [ k ] onde k é o número do índice, então s a [ k ] será o início de uma instância do comum substring e s a [ k - 1 ]L CPs L CPs l c p [ k ] k s a [ k ] s a [ k - 1 ] será o índice inicial da segunda instância. Obviamente, o comprimento é o valor na matriz lcp.
fonte
Eu tenho uma ideia que pode funcionar. Começamos com uma árvore sufixo generalizados para sequências de e T . Cada nó interno com sufixos S e T em sua subárvore corresponde a alguma substring comum das seqüências. Vamos chamar esses nós de não triviais. A substring comum é máxima, se o nó correspondente não tiver filhos não triviais. Se o nó v não for trivial, armazenamos a maior profundidade de cadeia de um nó não trivial em sua subárvore como l c s ( v ) . Se r é a raiz, então l c s ( r )S T S T v l c s ( v ) r l c s ( r ) é o comprimento da mais longa subsequência comum de e T .S T
Atualizar a árvore após excluir uma subcadeia de uma das seqüências não deve ser muito difícil. Primeiro, excluímos as folhas correspondentes aos sufixos excluídos, atualizando seus ancestrais quando necessário. Então começamos a processar os sufixos que precedem a substring excluída. Seja o menor ancestral não trivial da folha atual. Se o comprimento do sufixo for k (estamos a k passos da exclusão) e k < l c s ( v ) , temos que mover o sufixo para sua posição correta na árvore, atualizando os ancestrais quando necessário. Se k ≥ l c s ( v )v k k k<lcs(v) k≥lcs(v) , terminamos, pois não estamos interessados em subárvores com raízes triviais.
O algoritmo geral encontra repetidamente a substring comum mais longa de e T e exclui uma de suas ocorrências de ambas as seqüências, desde que o comprimento do LCS seja grande o suficiente.S T
Existem alguns aspectos técnicos, mas a ideia geral deve funcionar.
fonte
Comece com o texto concatenado S $ T , onde $ ocorre em nenhum lugar * ou T . Construa uma árvore / matriz de sufixos a partir deste texto. Agora é fácil percorrer essa estrutura de dados com sufixo para coletar todas as repetições máximas corretas. Examinando o contexto esquerdo, filtre as repetições máximas não esquerda. Essa filtragem para a esquerda pode ser implementada usando a tabela Burrows-Wheeler, como em Abouelhoda et al., Embora eu não acredite que isso seja necessário. Repetições ocorrendo apenas em S ou apenas em Ttambém deve ser eliminado neste momento. As repetições que não foram eliminadas são colocadas em uma fila de prioridades, com a prioridade definida pelo comprimento. Após o percurso, como as repetições gravadas são removidas da prioridade, a filtragem final (para contenção de substring) pode ser realizada. Dado o uso de frases máximas, no entanto, suspeito que muito pouco dessa filtragem seria necessária.
Este algoritmo é minha própria invenção. Eu não classificaria isso como muito inteligente, mas deveria funcionar.
fonte
fonte