Esse desafio é escrever código para resolver o seguinte problema.
Dadas duas seqüências A e B, seu código deve gerar os índices inicial e final de uma subseqüência de caracteres A com as seguintes propriedades.
- A substring de A também deve corresponder a alguma substring de B.
- Não deve mais haver substring de A que satisfaça a primeira propriedade.
Por exemplo:
A = xxxappleyyyyyyy
B = zapplezzz
A substring apple
com índices 4 8
(indexação de 1) seria uma saída válida.
Funcionalidade
Você pode assumir que a entrada estará no padrão em ou em um arquivo no diretório local, que é sua escolha. O formato do arquivo será simplesmente duas strings, separadas por uma nova linha. A resposta deve ser um programa completo e não apenas uma função.
Eventualmente, gostaria de testar seu código em duas substrings extraídas das strings em http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/ .
Ponto
Este é o código-golfe com um toque. Seu código deve ser executado no O(n)
tempo, onde n
é o comprimento total da entrada.
Línguas e bibliotecas
Você pode usar qualquer idioma que tenha um compilador / intérprete disponível gratuitamente / etc. para Linux. Você deve usar apenas bibliotecas de código-fonte aberto padrão não projetadas para resolver esta tarefa. Em caso de disputa, contarei isso como qualquer biblioteca que vem como padrão com o seu idioma ou que você pode instalar em uma máquina ubuntu padrão a partir de um repositório padrão.
Informação útil
Existem pelo menos duas maneiras de resolver esse problema em tempo linear. Um é primeiro calcular a árvore de sufixos e o segundo é primeiro calcular a matriz de sufixos e a matriz LCP.
- Aqui está uma explicação completa e (talvez exagerada) detalhada da construção linear de árvores com sufixo de tempo (verifica-se que algumas das figuras estão desarrumadas, infelizmente). Também há uma resposta SO muito agradável sobre a construção de árvores com sufixo de tempo linear em https://stackoverflow.com/questions/9452701/ukkonens-suffix-tree-algorithm-in-plain-english . Também inclui um link para o código fonte. Outra explicação detalhada pode ser encontrada aqui , desta vez fornecendo uma solução completa em C.
- A seção 2 de http://www.cs.cmu.edu/~guyb/realworld/papersS04/KaSa03.pdf fornece um algoritmo de construção de matriz de sufixos de tempo linear e o Apêndice A possui código fonte C ++. Esta resposta informa como calcular a substring comum mais longa https://cs.stackexchange.com/questions/9555/computing-the-longest-common-substring-of-two-strings-using-suffix-arrays . Seção 5 de https://courses.csail.mit.edu/6.851/spring12/scribe/lec16.pdf, que também possui uma vídeo aula associada https://courses.csail.mit.edu/6.851/spring12/lectures/L16 .html também explica o mesmo algoritmo a partir de 1:16:00.
fonte
O(n) time
Tem certeza de que é possível?Respostas:
Python 2, 646 bytes
Isso usa o algoritmo de inclinação descrito em "Construção de matriz de sufixo de trabalho linear simples" por Kärkkäinen e Sanders. A implementação de C ++ incluída nesse documento já parece um pouco complicada, mas ainda há muito espaço para reduzi-lo. Por exemplo, podemos recuar até chegar a uma matriz de comprimento um, em vez de causar um curto-circuito, como no papel, sem violar o
O(n)
requisito.Para a parte LCP, segui "Computação de prefixo mais longo em tempo linear em matrizes de sufixo e suas aplicações" por Kusai et al.
O programa gera
1 0
se a substring comum mais longa estiver vazia.Aqui está um código de desenvolvimento que inclui uma versão anterior do programa que segue a implementação do C ++ um pouco mais de perto, algumas abordagens mais lentas para comparação e um simples gerador de caso de teste:
fonte