我在文本文件上有一个长字符串(DNA序列,超过20 000个字符),我正在尝试找到其中重复至少三次的最长序列。实现这一目标的最佳方法是什么?
我能找到的唯一现有主题是在两个或多个单独的字符串中查找重复,但如何使用一个长字符串进行重复?
答案 0 :(得分:0)
如果我理解正确,您正在寻找解决“最长重复子字符串问题”:https://en.wikipedia.org/wiki/Longest_repeated_substring_problem
看一看 http://rubyquiz.com/quiz153.html
这个宝石可能会帮助您解决问题: https://github.com/luikore/triez
CTRL + F:“解决最长的常见子字符串问题:”
答案 1 :(得分:0)
准确地说,您正在寻找最长的3-fold substring。
字符串s的k重子串是s的重复子串,在s中出现至少k次
几年前有一个类似的python question会给你很多好消息。具体来看看Finding the Longest Multiple Repeat。有solution on GitHub但它也在Python中。
答案 2 :(得分:0)
str = "ababaeabadefgdefaba"
案例1:给定长度的子串不能重叠
n = 3
n.times.
flat_map { |i| str[i..-1].each_char.each_cons(n).to_a }.
uniq.
each_with_object({}) do |a,h|
r = /#{a.join('')}/
h[a.join('')] = str.scan(r).size
end.max_by { |_,v| v }
#=> ["aba", 3]
案例2:给定长度的子字符串可以重叠
只需要更改定义正则表达式的行:
n = 3
n.times.
flat_map { |i| str[i..-1].each_char.each_cons(n).to_a }.
uniq.
each_with_object({}) do |a,h|
r = /#{a.first}(?=#{a.drop(1).join('')})/
h[a.join('')] = str.scan(r).size
end.max_by { |_,v| v }
#=> ["aba", 4]
考虑案例2中执行的步骤:
n = 3
b = n.times
#=> #<Enumerator: 3:times>
c = b.flat_map { |i| str[i..-1].each_char.each_cons(n).to_a }
#=> [["a", "b", "a"], ["b", "a", "b"], ["a", "b", "a"], ["b", "a", "e"],
# ["a", "e", "a"], ["e", "a", "b"], ["a", "b", "a"], ["b", "a", "d"],
# ["a", "d", "e"], ["d", "e", "f"], ["e", "f", "g"], ["f", "g", "d"],
# ["g", "d", "e"], ["d", "e", "f"], ["e", "f", "a"], ["f", "a", "b"],
# ["a", "b", "a"], ["b", "a", "b"], ["a", "b", "a"], ["b", "a", "e"],
# ["a", "e", "a"], ["e", "a", "b"], ["a", "b", "a"], ["b", "a", "d"],
# ["a", "d", "e"], ["d", "e", "f"], ["e", "f", "g"], ["f", "g", "d"],
# ["g", "d", "e"], ["d", "e", "f"], ["e", "f", "a"], ["f", "a", "b"],
# ["a", "b", "a"], ["a", "b", "a"], ["b", "a", "e"], ["a", "e", "a"],
# ["e", "a", "b"], ["a", "b", "a"], ["b", "a", "d"], ["a", "d", "e"],
# ["d", "e", "f"], ["e", "f", "g"], ["f", "g", "d"], ["g", "d", "e"],
# ["d", "e", "f"], ["e", "f", "a"], ["f", "a", "b"], ["a", "b", "a"]]
d = c.uniq
#=> [["a", "b", "a"], ["b", "a", "b"], ["b", "a", "e"], ["a", "e", "a"],
# ["e", "a", "b"], ["b", "a", "d"], ["a", "d", "e"], ["d", "e", "f"],
# ["e", "f", "g"], ["f", "g", "d"], ["g", "d", "e"], ["e", "f", "a"],
# ["f", "a", "b"]]
e = d.each_with_object({}) do |a,h|
r = /#{a.first}(?=#{a.drop(1).join('')})/
puts " str.scan(#{r.inspect}) = #{str.scan(r)}" if a == d.first
h[a.join('')] = str.scan(r).size
puts " h[#{a.join('')}] = #{h[a.join('')]}" if a == d.first
end
#=> str.scan(/a(?=ba)/) = ["a", "a", "a", "a"]
#=> h[aba] = 4
#=> {"aba"=>4, "bab"=>1, "bae"=>1, "aea"=>1, "eab"=>1, "bad"=>1, "ade"=>1,
# "def"=>2, "efg"=>1, "fgd"=>1, "gde"=>1, "efa"=>1, "fab"=>1}
e.max_by { |_,v| v }
#=> ["aba", 4]
在计算e
时,对于传递给块的d
的第一个元素,块变量a
等于["a", "b", "a"]
,而/a(?=ba)/
中的正则表达式str.scan(/a(?=ba)/)
{1}}匹配a
中str
后面ba
的每个(?=ba)
。 $quiz = new Quiz();
$quiz->setTitle('A quiz.');
$quiz->setAuthor('Alexandre');
$quiz->setContent("Blabla…");
$em = $this->getDoctrine()->getManager();
$em->persist($quiz);
是一个积极的前瞻(不是比赛的一部分)。