Ce défi consiste à écrire du code pour résoudre le problème suivant.
Étant donné deux chaînes A et B, votre code doit générer les index de début et de fin d'une sous-chaîne de A avec les propriétés suivantes.
- La sous-chaîne de A doit également correspondre à une sous-chaîne de B.
- Il ne devrait plus y avoir de sous-chaîne de A qui réponde à la première propriété.
Par exemple:
A = xxxappleyyyyyyy
B = zapplezzz
La sous-chaîne apple
avec des index 4 8
(indexant à partir de 1) serait une sortie valide.
La fonctionnalité
Vous pouvez supposer que la saisie sera standard dans ou dans un fichier du répertoire local, à vous de choisir. Le format de fichier sera simplement deux chaînes, séparées par une nouvelle ligne. La réponse devrait être un programme complet et pas seulement une fonction.
Je voudrais éventuellement tester votre code sur deux chaînes extraites des chaînes de http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/ .
But
Ceci est du code-golf avec une torsion. Votre code doit être exécuté dans le O(n)
temps, où n
est la longueur totale de l'entrée.
Langues et bibliothèques
Vous pouvez utiliser n’importe quel langage disposant d’un compilateur / interprète / etc. Disponible gratuitement. pour Linux. Vous ne devez utiliser que des bibliothèques Open Source standard non conçues pour résoudre cette tâche. En cas de litige, je considérerai cela comme n'importe quelle bibliothèque fournie en standard avec votre langue ou que vous pourrez installer sur une machine Ubuntu par défaut à partir d'un référentiel par défaut.
Informations utiles
Il existe au moins deux façons de résoudre ce problème en temps linéaire. L'une consiste à calculer d'abord l'arbre de suffixe et la seconde à calculer d'abord le tableau de suffixes et le tableau LCP.
- Voici une explication complète et (peut-être trop) détaillée de la construction de l’arbre de suffixes temporels linéaires (il s’avère que certaines des figures sont malheureusement altérées). Il existe également une très bonne réponse SO concernant la construction de l’arborescence de suffixes temporels linéaires à l’ adresse https://stackoverflow.com/questions/9452701/ukkonens-suffix-tree-algorithm-in-plain-english . Il comprend également un lien vers le code source. Une autre explication détaillée peut être trouvée ici , donnant cette fois une solution complète en C.
- La section 2 de http://www.cs.cmu.edu/~guyb/realworld/papersS04/KaSa03.pdf donne un algorithme de construction de tableau de suffixes temporels linéaires et l'annexe A contient un code source C ++. Cette réponse vous indique comment alors calculer la plus longue sous-chaîne commune https://cs.stackexchange.com/questions/9555/computing-the-longest-common-substring-of-two-strings-using-suffix-arrays . La section 5 de https://courses.csail.mit.edu/6.851/spring12/scribe/lec16.pdf est également associée à une conférence vidéo https://courses.csail.mit.edu/6.851/spring12/lectures/L16. .html explique également le même algorithme à partir de 1:16:00.
la source
O(n) time
Es-tu sûr que c'est possible?Réponses:
Python 2, 646 octets
Ceci utilise l'algorithme de biais décrit dans "Construction de groupes de suffixes à travail linéaire simple" de Kärkkäinen et Sanders. L'implémentation C ++ incluse dans ce document semble déjà un peu "gaie", mais il y a encore beaucoup de place pour la rendre plus courte. Par exemple, nous pouvons recurse jusqu’à arriver à un tableau de longueur un, au lieu de court-circuiter comme dans le papier, sans violer l’
O(n)
exigence.Pour la partie LCP, j'ai suivi "Calcul du préfixe le plus long, le plus long et le plus linéaire dans les tableaux de suffixes et ses applications" de Kusai et al.
Le programme est généré
1 0
si la plus longue sous-chaîne commune est vide.Voici un code de développement qui inclut une version antérieure du programme qui suit de plus près l'implémentation de C ++, des approches de comparaison plus lentes et un simple générateur de cas de test:
la source