Estou procurando uma estrutura de dados que armazene um conjunto de seqüências de caracteres sobre um conjunto de caracteres , capaz de executar as seguintes operações. Denota- D ( S ) como a estrutura de dados que armazena o conjunto de cadeias S .
Add-Prefix-Set
em : dado um conjunto T de (possivelmente vazio) cordas, cujo tamanho é delimitada por uma constante e cuja cadeia comprimentos são delimitadas por uma constante, retorno D ( { t s | t ∈ T , s ∈ S } ) . Ambas as constantes delimitadoras são globais: eles são os mesmos para todas as entradas T .Get-Prefixes
em : retornar { a | a s ∈ S , a ∈ Σ } . Note que eu realmente não me importo com a estrutura usada para esse conjunto, desde que eu possa enumerar seu conteúdo em O ( | Σ | ) .Remove-Prefixes
em : retorna D ( { s | a s ∈ S , a ∈ Σ } ) .Merge
: dado e D ( T ) , retorne D ( S ∪ T ) .
Agora, eu realmente gostaria de fazer todas essas operações em , mas estou bem com uma estrutura que executa todas essas operações em o ( n ) , em que n é o comprimento da string mais longa no estrutura. No caso da fusão, que gostaria de um o ( n 1 + n 2 ) tempo de funcionamento, em que n 1 é n para o primeiro e n 2 o n para a segunda estrutura.
Um requisito adicional é que a estrutura seja imutável, ou pelo menos que as operações acima retornem estruturas 'novas', de modo que os ponteiros para as antigas ainda funcionem como antes.
Uma observação sobre amortização: tudo bem, mas você deve observar a persistência. Como reutilizo estruturas antigas o tempo todo, terei problemas se atingir o pior caso com um conjunto específico de operações na mesma estrutura (ignorando as novas estruturas criadas).
Eu gostaria de usar essa estrutura em um algoritmo de análise em que estou trabalhando; a estrutura acima conteria a aparência necessária para o algoritmo.
Já pensou em usar um trie , mas o principal problema é que eu não sei como mesclar tentativas de forma eficiente. Se o conjunto de cadeias de caracteres Add-Prefix-Set
consistir em apenas cadeias de caracteres únicos, você poderá armazenar esses conjuntos em uma pilha, o que forneceria tempo de execução para as três primeiras operações. No entanto, essa abordagem também não funciona para mesclagem.
Por fim, observe que não estou interessado em fatores : isso é constante para tudo que eu me importo.
fonte
Add-Prefix-Set
ou você começa com um conjunto arbitrário de strings?Add-Prefix-Set
lo em)Respostas:
Pensei por algum tempo, mas não encontrei o problema de fazer todas as suas operações da maneira mais estúpida possível em uma estrutura do DAG semelhante a um trie:
Add-Prefix-Set
Mesclar
Unir raízes de duas estruturas: torne todos os nós filhos do segundo filho filhos do primeiro nó. Agora você pode ter várias arestas marcadas com o mesmo caractere indo do mesmo nó.
Atualização lenta da raiz
Get-prefixos
Preguiçoso atualizar a raiz. Agora encontre todos os filhos da raiz e relate o conjunto de letras nas bordas que vão para eles.
Remover prefixos
Preguiçoso atualizar a raiz. Una todos os filhos da raiz e defina o ponteiro da raiz para o resultado dessa união. Atualize preguiçosamente a nova raiz.
Persistência
fonte