Ruby 如何找到字符串的最长重复序列

Ruby 如何找到字符串的最长重复序列,ruby,string,Ruby,String,我在一个文本文件中有一个长字符串(DNA序列,超过20000个字符),我试图找到其中最长的序列,它至少重复了三次。实现这一目标的最佳方式是什么 我能找到的唯一现有主题是在两个或多个单独的字符串中查找重复,但如何使用一个长字符串?如果我理解正确,您正在寻找解决“最长重复子字符串问题”: 看看 此gem可能会帮助您解决问题: CTRL+F:“解决最长的常见子字符串问题:”准确地说,您正在寻找最长的子字符串 字符串s的k倍子串是在s中至少出现k次的s的重复子串 几年前有一个类似的例子,会给你很多好

我在一个文本文件中有一个长字符串(DNA序列,超过20000个字符),我试图找到其中最长的序列,它至少重复了三次。实现这一目标的最佳方式是什么


我能找到的唯一现有主题是在两个或多个单独的字符串中查找重复,但如何使用一个长字符串?

如果我理解正确,您正在寻找解决“最长重复子字符串问题”:

看看

此gem可能会帮助您解决问题:


CTRL+F:“解决最长的常见子字符串问题:”

准确地说,您正在寻找最长的子字符串

字符串s的k倍子串是在s中至少出现k次的s的重复子串

几年前有一个类似的例子,会给你很多好的信息。具体来看。有一种方法,但在Python中也是如此

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.join('')}/
    h[a.join('')] = str.scan(r).size
end.max_by { |_,v| v }
  #=> ["aba", 3]
只需更改定义正则表达式的行:

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] 
n=3
b=n次
#=> # 
c=b.flat_map{i|str[i..-1]。每个字符。每个字符(n)。到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。每个带有对象({})do的对象都是a,h|
r=/{a.first}(?={a.drop(1).join(“”)})/
如果a==d,则将“str.scan(#{r.inspect})=#{str.scan(r)}”放在第一位
h[a.连接('')=str.scan(r).大小
如果a==d,则将“h[#{a.join(“”)}]=#{h[a.join(“”)]}”放在第一位
结束
#=>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|u乘{| |,v | v}
#=>[“aba”,4]
在计算
e
时,对于传递给块的
d
的第一个元素,块变量
a
等于
[“a”、“b”、“a”]
,并且
str.scan(/a(?=ba)/)中的regex
/a(?=ba)
匹配
str中紧跟
ba
的每个
a
(?=ba)
是正向前瞻(不是匹配的一部分)。

最长序列是一个特定的术语,还是等同于“最长子字符串”?序列/子串是否允许重叠?