【问题标题】:Efficient algorithm to find String overlaps查找字符串重叠的有效算法
【发布时间】:2011-03-13 16:30:52
【问题描述】:

我不会详细介绍我要解决的问题,但它处理的是一个大字符串,并涉及查找字符串中存在的重叠间隔。我只能使用其中一个重叠的区间,所以我想将这些区间分开并单独分析。我想知道使用什么算法来尽可能有效地做到这一点。

我必须强调,速度在这里是最重要的。我需要尽快分开间隔。我想到的算法是区间树,但我不确定这是否是我们能做的最好的。

可以在 O(log n) 时间内查询区间树,n 是区间数,构建需要 O(nlog n) 时间,但我想知道我们是否可以减少其中任何一个。

谢谢!

编辑:我知道这个问题很模糊。我为混乱道歉。我建议人们看看 Aaron Huran 和 cmets 的答案。这应该有助于澄清更多事情。

【问题讨论】:

  • “字符串中的重叠间隔”是什么意思?
  • String: "ThisIsATestStringToShowWhatIMeanByIntervals" 间隔:0-4, 5-13, 8-19, 10-12 这里,间隔 5-13, 8-19 和 10-12 重叠,所以,我只能使用其中之一。
  • 间隔总是按起点排序吗?
  • 所以间隔与正在处理的字符串无关?
  • 我认为这句话“涉及查找字符串中存在的重叠区间。我只能使用重叠的区间之一,所以我想将这些区间分开并单独分析。”需要进一步澄清

标签: algorithm string performance overlap intervals


【解决方案1】:

好吧,我昨晚很无聊,所以我用 Python 做了这个。它是不必要的递归(我刚读了 The Little Schemer 并认为递归现在非常简洁),但它解决了你的问题并处理了我扔给它的所有输入。

intervals = [(0,4), (5,13), (8,19), (10,12)]  

def overlaps(x,y): 
   x1, x2 = x 
   y1, y2 = y 
   return ( 
      (x1 <= y1 <= x2) or 
      (x1 <= y2 <= x2) or  
      (y1 <= x1 <= y2) or 
      (y1 <= x2 <= y2) 
   ) 

def find_overlaps(intervals, checklist=None, pending=None): 
   if not intervals:  
      return [] 

   interval = intervals.pop() 

   if not checklist: 
      return find_overlaps(intervals, [interval], [interval]) 

   check = checklist.pop() 

   if overlaps(interval, check): 
      pending = pending or [] 
      checklist.append(check) 
      checklist.append(interval) 
      return pending + [interval] + find_overlaps(intervals, checklist) 
   else: 
      intervals.append(interval) 
      return find_overlaps(intervals, checklist) 

这样使用:

>>> find_overlaps(intervals)
[(10, 12), (8, 19), (5, 13)]

请注意,它会以起始点的 REVERSE 顺序返回所有重叠间隔。希望这是一个小问题。这只是因为我在列表中使用push()pop(),它在列表的末尾运行,而不是insert(0)pop(0),它在开头运行。

这并不完美,但它以线性时间运行。还要记住,实际字符串的大小根本不重要——运行时间与间隔数有关,而不是字符串的大小。

【讨论】:

  • 是的,我知道字符串的长度无关紧要。我也在线性时间内实现了类似的东西,但我希望我能做得更好。我认为区间树可以让我们降低到 O(log n),尽管我还没有正确阅读它们。
  • g 函数是什么?您是否误漏了某些内容,或者是某种 Python 内置(我在互联网上找不到)?
  • 我认为这实际上是 O(n^2) 的重叠间隔数,因为在每次迭代中,您将所有先前找到的元素一起复制到一个新列表中与新发现的。另外,我相信您取决于预先排序的间隔,即 O(n log n)
【解决方案2】:
【解决方案3】:

您正在计算两个字符串之间的差异,对吗?你想用什么语言来做这个?

更新: 如果没有任何关于如何选择要使用的间隔的标准,那么有很多可能的解决方案。

一种方法是取最低的起始数字,抓住它的结尾。 获取高于前一个区间结束的下一个起始数字。获取此间隔的结束并重复。

所以对于 0-4、5-13、8-19、10-12 你得到:0-4、5-13 并忽略其他。

【讨论】:

  • 我正在使用 Java,但我不想计算两个字符串之间的差异。我只有一个字符串,其中定义了多个间隔。我需要使用这些区间进行一些计算,但我只能使用所有重叠区间中的一个,这就是我希望将它们分开的原因。
  • @Dharmesh:“在其中定义的多个间隔”是什么意思?您是否正在尝试解析数据格式?如果是这样,您能否提供一些示例输入?
  • 我已将分数附加到字符串间隔,我需要分数最高的那个。因此,可能是 10-12 区间的得分最高,但如果我们使用您上面描述的方法,我们将有 O(n) 的运行时间。
  • 另外,上面的 cmets 中有示例输入。
猜你喜欢
  • 2010-11-20
  • 2014-12-09
  • 2017-08-05
  • 2014-10-31
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
相关资源
最近更新 更多