Encuentra la distancia mínima de edición entre dos cadenas

13

Explicación

La distancia de edición entre dos cadenas es una función del número mínimo posible de inserciones, eliminaciones o sustituciones para convertir una palabra en otra.

Las inserciones y eliminaciones cuestan 1 y las sustituciones cuestan 2.

Por ejemplo, la distancia entre ABy Aes 1, porque las eliminaciones cuestan 1 y la única edición necesaria es la eliminación del Bcarácter.

La distancia entre CARy FARes 2, porque las sustituciones cuestan 2. Otra forma de ver esto es una eliminación y una inserción.

Reglas

Dadas dos cadenas de entrada (proporcionadas, sin embargo, es conveniente en su idioma), su programa debe encontrar la distancia mínima de edición entre las dos cadenas.

Puede suponer que las cadenas solo contienen los caracteres A-Zy tienen menos de 100 caracteres y más de 0 caracteres.

Este es el código de golf , por lo que gana la solución más corta.

Ejemplos de casos de prueba

ISLANDER, SLANDER
> 1
MART, KARMA
> 5
KITTEN, SITTING
> 5
INTENTION, EXECUTION
> 8
Peter Olson
fuente
Hice esto en Excel en mi clase de algoritmos una vez. Fue un poco divertido entregar el proyecto como un documento .xls. En realidad funcionó bastante bien. Veré si puedo encontrarlo.
captncraig
PHP debería ganar esto fácilmente.
st0le
@ st0le: la levenshteinfunción integrada trata las sustituciones como una edición (sustituto), no dos (eliminar + insertar).
Sr. Llama

Respuestas:

7

brainfuck, 2680

+>>>>>>>>>>>>>>>>>>>>>>++++++>,<[->-----<]>--[+++++++++++++++++++++
+++++++++++>>[->>+<<]>>+<<,--------------------------------]>>[-<<<
+>>>]<<<<[>[-<<+>>]<<<]>[-<<<<<+>>>>>]>[>>],----------[++++++++++>>
[->>+<<]>>+<<,----------]>>[-<<<+>>>]<<<<[>[-<<+>>]<<<]>[-<<+>>]<<[
-<+>>+<]<<<[->+<]>[-<+>>>>+<<<]>>>[-<+>]<[->+>+<<]<[-<+>]<[->+>+<<]
<[-<+>>+<]<[->+<]>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<[->>+
>+<<<]>>>[-<<<+>>>]<[->>+[->+>+<<]<<[->>+<<]>>]>>[-]<[<<]<<<+[->>>+
<<<]>>>[-<+<<+>>>]<<<<<[->>[->>>>[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>
+<<]>>>>]>>[->>>>+<<<<]>>>>[-<<<<+<<+>>>>>>]<<+[->>+<<]>>[-<<+<+>>>
]<<<<<<<<]>>[-]>>[-]>>[-]-[+<<-]+>>>>>>>>>>>>>>>>>[-<+>]<[->+<<<<+>
>>]<<<[->>>>>>[-<+>]<[->+<<<<+>>>]<<<<<<<[-]<<+>>>>>>[-<<<<+>>>>>>>
>>>[-<+>]<[->+>+<<]<<<<<<<<<[->+<]>[->>>>>>>>+<<<<<<<<<+>]<<<[->+<]
>[->>>>>>>>+<<<<<<<<<+>]>>>>>>>>>[-<<<<<+>>>>>]<<<<<[->>+>>>+<<<<<]
>>>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>>>]<<<<<<+>>-
[-<<[-<<<<+>>>>]<<<<[->>+>>+<<<<]>>[->>>>>>[->>+<<]<<[->>+<<]<<[->>
+<<]<<[->>+<<]>>]>>>>]>>[->>+<<]>>[-<<+>>>>+<<]->>-[-[->>+<<]>>]>[-
>+<]>[-<+>>>+<<]<<<[->+<]>[-<+>>>+<<]+[->>[-<<+>>]>>[-<<+>>]<<<<<<+
]<<<<<<[->>>>>>+<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<[->>>>+<<<<]
-<<[-]>>>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<[->>[->>+<<]<<[->>+<<]>>]>>-[
-[->>+<<]>>]<[->+<]>[-<+>>>+<<]+[->>[-<<+>>]<<<<+]>>[-<<+>>]<<<<<<<
<-[+>>[-<<+>>]>>[-<<+>>]>>[-<<+>>]<<<<<<<<-]+>>>[-]<[->+<]>>>[-]<[-
>+<]>>>[-]<[->+<]>>>[->+<]>[-<+>>>>>>>>>>>>>+<<<<<<<<<<<<]>>>>>>>>>
>>>-[-[->>+<<]>>]>[->+<]>[-<+<+>>]<<<<-[+>>[-<<+>>]<<<<-]+>>[-<+>]>
>>>>>>>>[->+<]>[-<+>>>>>>>>>>>+<<<<<<<<<<]>>>>>[->+<]>[-<+>>>>>+<<<
<]>>>>-[-[->>+<<]>>]>[->+<]>[-<+<+>>]<<<<-[+>>[-<<+>>]<<<<-]+>[->-<
]>[-<[-]+>]<[->>>+<<<]>>>[-<<+<+>>>]<<-[+>[->+<]<]<[->>+<-[[-]>[->+
<]>[-<+>>>+<<]+>>[-<<[-]>>]<[->+<]>[-<+>>>+<<]+>>[-<<[-]>>]<[->+<]>
[-<+>>>+<<]+>>[-<<[-]>>]<<[-<<[-]+>>]<<[-<<[-]+>>]<<[-<<[-]+>>]<<<+
>->->>->>-<<<<<]<[->+<]]>[-<+>]>>[-<<<+>>>]<<<[->>>>>>>>>>>>>+<<<<<
<<<<<<<<]>>>>>>>>[->+<]>[-<+>>>>>>>>>+<<<<<<<<]>[->+<]>[-<+>>>>>>>>
>+<<<<<<<<]>>>>>>>>>[->>>+<<<]>>>[-<<+<+>>>]<<<<<[->>>>>+<<<<<]>>>>
>[-<<<<<+<<<+>>>>>>>>]<<<<<<<<+>>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]
<<[->>+<<]<<[->>+<<]>>>>>>>>>>]<<<<[-<<[-<<<<<<+>>>>>>]<<<<<<[->>+>
>>>+<<<<<<]>>[->>>>>>>>[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>+<<]<<[->>
+<<]>>]>>>>>>]<<[-]<<[->>>>+<<<<]>>>>>>[-[->>+<<]<<[->>+<<]>>>>]<<[
->>>>>+<<<<<]-[+<<-]+>>>>>>>>>>>>>>>]<<]>>>>>>>>[->+<]<<[->+<]<<[->
+<]>>>>>[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<<<[->>[->>>>+<<<<]>>
>>[-<<+<<+>>>>]<<+[-[->>+<<]<<[->>+<<]<<[->>+<<]>>>>>>]<<<<]>>[-[->
>+<<]>>]>>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>[->-[>+>>]>
[+[-<+>]>+>>]<<<<<]>[-]<++++++[->++++++++[->+>+<<<<+>>]<]>>>.<.<<<.

Usando programación dinámica, por supuesto.

Las cadenas de entrada deben estar separadas por un espacio y seguidas de una nueva línea. Por ejemplo:

INTENTION EXECUTION
008
caja de cartón
fuente
1
Bien alineado y muy legible: ¡me gusta, +1!
Thomas
¿Es este un lenguaje de computadora? : O
Esta es la presentación más confusa a esta pregunta ... +1 solo porque es BF.
HyperNeutrino
5

Python, 138 148 152 caracteres

Ok, conocía el principio pero nunca antes había implementado la distancia de edición, así que aquí va:

x,y=raw_input().split()
d=range(99)
for a in x:
 c=d;d=[d[0]+1]
 for b,p,q in zip(y,c[1:],c):d+=[min(d[-1]+1,p+1,q+2*(a!=b))]
print d[-1]
han
fuente
4

PHP, 40

Sigue las reglas según lo establecido, pero no el espíritu de las reglas:

<?=levenshtein($argv[1],$argv[2],1,2,1);

Toma sus dos parámetros como argumentos. Ejemplo de llamada: php edit_dist.php word1 word2.
Normalmente levenshtein()considera una sustitución como una operación, pero tiene un formulario sobrecargado donde se pueden especificar los pesos de inserción / sub / eliminación. En este caso, es 1/2/1.

Señor llama
fuente
3

APL (90 caracteres)

⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞

Estoy usando Dyalog APL como mi intérprete, con ⎕IOset a 1 y ⎕MLset a 0. La función directa ( { ... }) calcula, dada una fila como entrada, la siguiente fila en la matriz de distancia. (Se inicia con la fila inicial:. 0,⍳x) El operador de potencia ( ) se usa para anidar la función una vez para cada carácter en la segunda cadena ( ⊃⍴b). Después de todo eso, la fila final se invierte ( ), y se toma su primer elemento ( ).

Ejemplo:

      ⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞
LOCKSMITH
BLACKSMITH
3
      ⊃⌽({h←1+c←⊃⍵⋄d←h,1↓⍵⋄h,(⊂⍵){y←⍵+1⋄d[y]←⍺{h⌷b=⍵⌷a:⍵⌷⍺⋄1+d[⍵]⌊y⌷⍺}⍵}¨⍳x}⍣(⊃⍴b←,⍞))0,⍳x←⍴a←,⍞
GATTTGTGACGCACCCTCAGAACTGCAGTAATGGTCCAGCTGCTTCACAGGCAACTGGTAACCACCTCATTTGGGGATGTTTCTGCCTTGCTAGCAGTGCCAGAGAGAACTTCATCATTGTCACCTCATCAAAGACTACTTTTTCAGACATCTCCTGTAG
AAGTACTGAACTCCTAATATCACCAATTCTTCTAAGTTCCTGGACATTGATCCGGAGGAGGATTCGCAGTTCAACATCAAGGTAAGGAAGGATACAGCATTGTTATCGTTGTTGAGATATTAGTAAGAAATACGCCTTTCCCCATGTTGTAAACGGGCTA
118
Dillon Cower
fuente
3

R 51

Esto se lee en dos líneas del usuario (que son la entrada) y luego solo usa la adistfunción para calcular la distancia. Dado que las sustituciones cuestan 2 para este problema, necesitamos agregar un vector con nombre para el parámetro de costos para adist. Como también hay un parámetro de recuento para adist, solo podemos acortar los costos a cos, por lo que todavía tenemos una coincidencia única para los nombres de los parámetros.

x=readLines(n=2);adist(x[1],x[2],cos=c(i=1,d=1,s=2))

Ejemplo de uso

> x=readLines(n=2);adist(x[1],x[2],cos=c(i=1,d=1,s=2))
MART
KARMA
     [,1]
[1,]    5
Razón
fuente
0

Ruby 1.9, 124

l=->a,b{a[0]?b[0]?[(a[0]==b[0]?-1:1)+l[a[1..-1],b[1..-1]],l[a[1..-1],b],l[a,b[1..-1]]].min+1: a.size: b.size}
puts l[*ARGV]

Versión de golf del lento y recursivo método de Ruby aquí , modificado para duplicar el peso de las sustituciones. El hecho de que se necesitan 7 caracteres para eliminar el primer carácter de una cadena realmente duele, y sería genial reemplazarlo (a[0]==b[0]?-1:1)por algo así, -1**a[0]<=>b[0]pero el orden de las operaciones no es mi amigo.

histocrat
fuente
0

Smalltalk (Smalltalk / X), 34

Tengo suerte: la clase estándar "String" ya contiene levenshtein:

entrada a, b:

a levenshteinTo:b s:2 k:2 c:1 i:1 d:1

(los parámetros adicionales permiten diferentes pesos en la sustitución, eliminación, etc.)

Prueba de funcionamiento:

#( 'ISLANDER'  'SLANDER' 
   'MART'      'KARMA'   
   'KITTEN'    'SITTING' 
   'INTENTION' 'EXECUTION'  
) pairWiseDo:[:a :b|
    a print. ' ' print. b print. ' ' print.
    (a levenshteinTo:b
            s:2 k:2 c:1 i:1 d:1) printCR.
].

->

ISLANDER SLANDER 1
MART KARMA 5
KITTEN SITTING 5
INTENTION EXECUTION 8
blabla999
fuente