当前位置: 首页 > 知识库问答 >
问题:

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

林博厚
2023-03-14

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

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

共有2个答案

谭裕
2023-03-14
str = "ababaeabadefgdefaba"  
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]
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”],并且str.scan(/a(?=ba)/)中的regex/a(?=ba)匹配str中紧跟ba的每个a<代码>(?=ba)是一个正向前瞻(不是匹配的一部分)。

壤驷阳波
2023-03-14

如果我理解正确,您希望解决“最长重复子串问题”:https://en.wikipedia.org/wiki/Longest_repeated_substring_problem

看看http://rubyquiz.com/quiz153.html

此gem可能会帮助您解决问题:https://github.com/luikore/triez

CTRL F:“解决最长的公共子字符串问题:”

 类似资料:
  • 我需要找到字符串中最长的序列,并警告序列必须重复三次或更多次。例如,如果我的字符串是: fdwaw4helloworld vcdv1c3xcv3xcz1sda21f2sd1ahelloworld gafgfa4564534321fadghelloworld 然后我希望返回值“helloworld”。 我知道有几种方法可以做到这一点,但我面临的问题是,实际的字符串太大了,所以我真的在寻找一种能够及时

  • 我正在学习最长公共子序列,使用以下算法: 公共级LCS{ 但是程序返回一个ErrorCharAt(未知来源),并且没有做任何事情。 另外,如果我将int i和j更改为0,那么下面的E将是索引-1和错误 我现在很迷路。有人能帮我吗?

  • 题目描述 输入一个字符串(只包含 a~z 的字符),求其最长不含重复字符的子字符串的长度。例如对于 arabcacfr,最长不含重复字符的子字符串为 acfr,长度为 4。 解题思路 // java public int longestSubStringWithoutDuplication(String str) { int curLen = 0; int maxLen = 0;

  • 解决此问题的最佳方法(性能方面)是什么?有人建议我使用后缀树。这是最好的方法吗?

  • 我知道如何使用动态规划来解决 <罢工> 大多数 给定两个字符串的最长公共子串或最长公共子串。然而,对于字符串Y的子串X的最长子序列问题,我很难找到一个解决方案。 查找字符串X的所有子序列并按长度desc排序; 遍历排序的子序列,如果当前子序列是Y的子字符串,则返回子序列。 它可以工作,但运行时间可能会很糟糕。假设X中的所有字符都是唯一的,那么有2^m个子群,其中m是X的长度,我认为检查一个字符串是

  • 我有一个tweet数据库,其中实际的tweet文本在一个名为“text”的字段中。 我想知道如何查询并显示最长的tweet?我一直在想也许.排序或.长度或诸如此类的东西,但我环顾四周,到目前为止还没有找到任何有用的东西。 救命啊!谢谢!