2015-02-24 2 views
1

Есть ли какая-либо функция в ruby, которая сравнивает две строки и возвращает количество символов, которые у них есть общего?Функция, которая возвращает количество общих символов в рельсах

+0

Я не знаю такого встроенного метода, но вы можете написать один если вы определите свое проблемное пространство немного лучше. Можете привести несколько примеров? И я полагаю, что это не домашнее задание? :) –

+0

Это не домашнее задание :) Я хочу реализовать алгоритм jaro-winkler, и первым шагом будет вычисление m, где m - количество совпадающих символов в тех же позициях (я забыл упомянуть об этом в моем вопросе). Например, для «CRATE» a «TRACE» m равно 3 (они имеют R, A, E в общих положениях: 1, 2 и 3). Но я полагаю, что я сделаю это самостоятельно – Madalina

+0

Если это так, то это XY-проблема. – sawa

ответ

2

Сдача в аренду:

s1 = "abacad" 
s2 = "bagfa" 

Вы можете написать:

(s1.chars & s2.chars).size 
    #=> 2 

Если вы хотите сосчитать дубликаты:

s1.chars.uniq.reduce(0) { |cnt,c| cnt + [s1.count(c), s2.count(c)].min } 
    #=> 3 

edit1: После прочтения @ комментарий ChrisHeald, я вижу OP добавила дополнительное требование в комментарий: соответствие ch атракторы занимают одинаковые позиции. В этом случае еще проще:

s1.chars.zip(s2[0,[s1.size, s2.size].min].chars).count { |c1,c2| c1==c2 } 
    #=> 1 

я был вынужден изменить то, что я изначально имел, как и @ChrisHeald указал на проблему. К сожалению, исправление принесло с собой уклонение (а также временную строку и еще один временный массив).

Мы

a = s1.chars.zip(s2.chars) 
    #=> [["a", "b"], ["b", "a"], ["a", "g"], ["c", "f"], ["a", "a"], ["d", nil]] 
a.count { |c1,c2| c1==c2 } 
    #=> 1 

Edit2:

Чтобы избежать создания промежуточных массивов:

[s1.size, s2.size].min.times.count { |i| s1[i] == s2[i] } 
    #=> 1 
+0

Это вернет все общие символы, а не все обычные символы в том же положении. 's1 =" ab "; s2 = "ba" 'дает вам * m * of 2, когда оно должно быть 0. –

+0

@ Крис, я собирался ответить на вопрос, не заметив дополнительной информации в комментарии OP. (Не люди замечают кнопку «изменить»?) Я могу что-то добавить. –

+0

Упрощенный для действительного решения, но я хочу указать, что это создаст n + 1 промежуточных массивов (где n - длина строки) и не будет работать, если строки имеют несоответствующие размеры; для обработки строк это, вероятно, нежелательные черты. –

1

Существует не один, но это тривиально, чтобы написать одно:

def matching_chars(str1, str2) 
    chars, index = str2.chars, -1 
    str1.chars.count {|c| chars[index += 1] == c } 
end 

Просто перебирать один символов струны и подсчитать количество раз, что он соответствует символу в позиции другой струны.

Смежные вопросы