2012-03-22 23 views
10

Id como para comparar dos cadenas en Ruby y encontrar su similitudRubí comparar dos cadenas porcentaje de similitud

que he tenido un vistazo a la Levenshtein tesoro, pero parece que esto se actualizó por última en 2008 y no puedo encontrar documentación de cómo usarlo. Con algunos blogs que sugiere su roto

Probé la joya text con Levenshtein pero le da un número entero (más pequeño es mejor)

Obviamente, si las dos cadenas son de longitud variable que a tener problemas con el Levenshtein Algoritmo (Say comparando dos nombres, donde uno tiene un segundo nombre y otro no).

¿Qué sugieres que haga para obtener una comparación porcentual?

Editar: Im buscando algo similar a la de PHP similar text

+0

posiblemente duplicado de http://stackoverflow.com/questions/4761793/how-to-do-advanced-string-comparison-in-ruby –

+0

Esto genera una lista de diferencias, estoy buscando un% de similitud – Akshat

+0

Si el las cadenas tienen diferente longitud, ¿cuál debería tomarse como base para calcular el porcentaje? –

Respuesta

14

Creo que su pregunta se podría hacer con algunas aclaraciones, pero esto es algo rápido y sucio (cálculo como porcentaje de la cadena más larga como por su aclaración anterior) :

def string_difference_percent(a, b) 
    longer = [a.size, b.size].max 
    same = a.each_char.zip(b.each_char).select { |a,b| a == b }.size 
    (longer - same)/a.size.to_f 
end 

todavía no estoy seguro de cómo mucho sentido esta diferencia porcentual que están buscando las marcas, pero esto debe empezar por lo menos.

Es un poco como la distancia Levensthein, ya que compara las cuerdas carácter por carácter. Entonces, si dos nombres difieren solo por el segundo nombre, en realidad serán muy diferentes.

+0

¿Alguien puede explicar el "mismo" bit? Por lo tanto, pasa por encima de cada carácter, mientras que el zip crea una matriz para cada personaje de la cadena A con lo que yo esperaría que fuera cada carácter de la secuencia B. ¿Cómo sabe el segundo cada_char qué índice concatenar en la matriz? –

+0

Además, este cálculo no funciona bien cuando se cambia un carácter al principio. –

+1

Tenga cuidado con ** a ** en Select, porque borra la variable pasada por parámetro. Es mejor usar otras letras. 'same = a.each_char.zip (b.each_char) .select {| c, d | c == d} .size' – sesperanto

12

Ahora hay una gema ruby ​​para similar_text. https://rubygems.org/gems/similar_text Proporciona un método similar que compara dos cadenas y devuelve un número que representa el porcentaje de similitud entre las dos cadenas.

+2

gema de texto similar se congela en grandes cadenas, intenté la página html 143kb –

9

Puedo recomendar la gema fuzzy-string-match.

Se puede utilizar como esto (tomado de the docs):

require "fuzzystringmatch" 
jarow = FuzzyStringMatch::JaroWinkler.create(:native) 
p jarow.getDistance("jones", "johnson") 

le proporcione una puntuación ~0.832 que cuenta cómo buen partido esas cadenas.

Cuestiones relacionadas