Вот решение для массивных струн. Я делаю поиск текста в текстовых строках размером 4,5 МБ, а другие решения останавливаются. Это использует тот факт, что ruby .split очень эффективен по сравнению со сравнениями строк.
def indices_of_matches(str, target)
cuts = (str + (target.hash.to_s.gsub(target,''))).split(target)[0..-2]
indicies = []
loc = 0
cuts.each do |cut|
loc = loc + cut.size
indicies << loc
loc = loc + target.size
end
return indicies
end
Это в основном использование лошадиных сил за методом .split, затем использование отдельных частей и длины искомой строки для определения местоположения. Я перешел от 30 секунд, используя различные методы, к мгновенным на очень больших строках.
Я уверен, что есть лучший способ сделать это, но:
(str + (target.hash.to_s.gsub(target,'')))
добавляет что-то к концу строки в случае, если цель находится в конце (и способ разделения), но также необходимо убедиться, что «случайное» добавление не содержит самой цели.
indices_of_matches("a#asg#sdfg#d##","#")
=> [1, 5, 10, 12, 13]