La distanza di modifica (o Levenshtein) tra due stringhe è il numero minimo di inserimenti, eliminazioni e sostituzioni di caratteri singoli necessari per trasformare una stringa nell'altra. Se le due stringhe hanno lunghezza n ciascuna, è noto che ciò può essere fatto in tempo O (n ^ 2) mediante la programmazione dinamica. Il seguente codice Python esegue questo calcolo per due stringhe s1
e 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]
In questo compito devi avvicinarti il più possibile al calcolo della distanza di modifica ma con una severa restrizione della memoria. Il tuo codice è autorizzato a definire un array contenente 1000 numeri interi a 32 bit e questo deve essere l'unico archivio temporaneo che usi nel tuo calcolo. Tutte le variabili e le strutture di dati devono essere contenute in questo array. In particolare, non saresti in grado di implementare l'algoritmo sopra per stringhe di lunghezza 1000 in quanto richiederebbe di memorizzare almeno 1.000.000 di numeri. Laddove la tua lingua non abbia naturalmente numeri interi a 32 bit (ad esempio Python) devi semplicemente assicurarti di non memorizzare mai un numero maggiore di 2 ^ 32-1 nell'array.
Puoi leggere i dati utilizzando qualsiasi libreria standard di tua scelta senza preoccuparti delle restrizioni di memoria in quella parte. Al fine di rendere la competizione leale per la parte principale del codice, è possibile utilizzare solo operazioni funzionalmente equivalenti a quelle del linguaggio di programmazione C e non utilizzare librerie esterne.
Per essere più chiari, la memoria per archiviare i dati di input o utilizzati dall'interprete della tua lingua, JVM ecc. Non conta ai fini del tuo limite e potresti non scrivere nulla sul disco. È necessario supporre che i dati di input siano di sola lettura quando sono in memoria, quindi non è possibile riutilizzarli per guadagnare più spazio di lavoro.
Cosa devo implementare?
Il codice dovrebbe essere letto in un file nel seguente formato. Avrà tre righe. La prima riga è la vera distanza di modifica. Il secondo è la stringa 1 e il terzo è la stringa 2. Lo testerò con i dati di esempio su https://bpaste.net/show/6905001d52e8 dove le stringhe hanno lunghezza 10.000 ma non dovrebbero essere specializzate per questi dati. Dovrebbe generare la minima distanza di modifica che può trovare tra le due stringhe.
Dovrai anche dimostrare che la distanza di modifica proviene effettivamente da una serie valida di modifiche. Il tuo codice dovrebbe avere un interruttore che lo trasforma in una modalità che può usare più memoria (quanto vuoi) e produce le operazioni di modifica che danno la distanza di modifica.
Punto
Il tuo punteggio sarà il (optimal edit distance/divided by the edit distance you find) * 100
. Per iniziare, nota che puoi ottenere un punteggio semplicemente contando il numero di disallineamenti tra le due stringhe.
Puoi usare qualsiasi lingua che ti piace che è liberamente disponibile e facile da installare in Linux.
Pausa
In caso di tie-break, eseguirò il tuo codice sulla mia macchina Linux e il codice più veloce vince.
{ uint32_t foo[1000]; for (foo[0] = 0; foo[0] < 5; ++foo[0]) printf("%d ", foo[0]); }
che verrà chiamato il tuo array di numeri interi a 32 bit foo
.
for(int i=0;i<=5;i++)
permesso perché sta archiviando i datii
?