La distance d'édition (ou Levenshtein) entre deux chaînes est le nombre minimal d'insertions, de suppressions et de substitutions de caractère unique nécessaires pour transformer une chaîne en l'autre. Si les deux chaînes ont chacune une longueur n, il est bien connu que cela peut se faire en temps O (n ^ 2) par programmation dynamique. Le code Python suivant effectue ce calcul pour deux chaînes s1
et s2
.
def edit_distance(s1, s2):
l1 = len(s1)
l2 = len(s2)
matrix = [range(l1 + 1)] * (l2 + 1)
for zz in range(l2 + 1):
matrix[zz] = range(zz,zz + l1 + 1)
for zz in range(0,l2):
for sz in range(0,l1):
if s1[sz] == s2[zz]:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz])
else:
matrix[zz+1][sz+1] = min(matrix[zz+1][sz] + 1, matrix[zz][sz+1] + 1, matrix[zz][sz] + 1)
return matrix[l2][l1]
Dans cette tâche, vous devez vous rapprocher le plus possible du calcul de la distance de montage, mais avec une restriction de mémoire sévère. Votre code est autorisé à définir un tableau contenant 1 000 entiers 32 bits et ce doit être le seul stockage temporaire que vous utilisez dans votre calcul. Toutes les variables et structures de données doivent être contenues dans ce tableau. En particulier, vous ne pourriez pas implémenter l'algorithme ci-dessus comme pour les chaînes de longueur 1000 car il vous faudrait stocker au moins 1 000 000 de numéros. Lorsque votre langue n'a pas naturellement des entiers 32 bits (par exemple Python), vous devez simplement vous assurer de ne jamais stocker un nombre supérieur à 2 ^ 32-1 dans le tableau.
Vous pouvez lire les données en utilisant n'importe quelle bibliothèque standard de votre choix sans vous soucier des restrictions de mémoire dans cette partie. Afin de rendre la compétition équitable pour la partie principale de votre code, vous ne pouvez utiliser que des opérations fonctionnellement équivalentes à celles du langage de programmation C et ne pouvez utiliser aucune bibliothèque externe.
Pour être plus clair, la mémoire pour stocker les données d'entrée ou utilisées par l'interpréteur de votre langue, JVM, etc. ne compte pas dans votre limite et vous ne pouvez rien écrire sur le disque. Vous devez supposer que les données d'entrée sont en lecture seule lorsqu'elles sont en mémoire, vous ne pouvez donc pas les réutiliser pour gagner plus d'espace de travail.
Que dois-je mettre en œuvre?
Votre code doit être lu dans un fichier au format suivant. Il aura trois lignes. La première ligne est la vraie distance d'édition. La seconde est la chaîne 1 et la troisième est la chaîne 2. Je vais la tester avec les exemples de données à https://bpaste.net/show/6905001d52e8 où les chaînes ont une longueur de 10 000 mais elles ne devraient pas être spécialisées pour ces données. Il doit produire la plus petite distance d'édition qu'il puisse trouver entre les deux chaînes.
Vous devrez également prouver que votre distance d'édition provient en fait d'un ensemble valide de modifications. Votre code doit avoir un commutateur qui le transforme en un mode qui peut utiliser plus de mémoire (autant que vous le souhaitez) et génère les opérations d'édition qui donnent votre distance d'édition.
But
Votre score sera le (optimal edit distance/divided by the edit distance you find) * 100
. Pour commencer, notez que vous pouvez obtenir un score en comptant simplement le nombre de discordances entre les deux chaînes.
Vous pouvez utiliser n'importe quelle langue de votre choix, librement disponible et facile à installer sous Linux.
Jeu décisif
Dans le cas d'un bris d'égalité, je vais exécuter votre code sur ma machine Linux et le code le plus rapide l'emporte.
{ uint32_t foo[1000]; for (foo[0] = 0; foo[0] < 5; ++foo[0]) printf("%d ", foo[0]); }
ceci En supposant que votre tableau d'entiers 32 bits sera appelé foo
.
for(int i=0;i<=5;i++)
autorisé car il stocke des donnéesi
?