【问题标题】:Efficient algorithm for MEM finding寻找 MEM 的高效算法
【发布时间】:2015-02-09 09:47:58
【问题描述】:

MEM是“Maximum Exact Matching”问题的缩写,该问题的目的是找到两个输入字符串之间的所有最大相似子串。请注意,这个问题与字符串匹配问题(或文本搜索)有点不同,您想在另一个文本中找到给定的字符串。

例如,在以下两个字符串中(具有有限字符 {1,2,3}),MEM 是“12”和“3312”

str1:"12233312"

str2:"123312"

例如 233 也是两个输入字符串之间的公共子字符串,但由于还有另一个更大的子字符串包含它,我们不将其视为 MEM。

有没有人有一些优雅的想法如何解决它。一个非常简单的想法可以是使用搜索算法来查找大字符串中较小字符串的所有可能子字符串,并使用一些快速字符串搜索算法,如 Boyer–Moore。但这似乎不是解决这个问题的有效方法。

【问题讨论】:

  • 这不就是最长公共子串“问题”吗? en.wikipedia.org/wiki/Longest_common_substring_problem
  • 我不仅要寻找一个共同的最大子串,还要寻找所有可能的共同最大子串。但也许我可以使用这个想法
  • 233 包含在更大的公共子字符串中。

标签: string algorithm search pattern-matching


【解决方案1】:

这是一个线性时间算法。

  1. str1 + "X" + str2 上构建后缀树,其中'X' 不会出现在str1str2 中。

  2. 一些叶节点对应于以str1 开头的后缀(包含'X')。把这些涂成红色。其他颜色为蓝色。

  3. 遍历树从根到叶,用从根到它的字符串长度标记每个节点。

  4. 遍历树的叶子到根,找到同时具有红色后代和蓝色后代的最叶子节点。步骤 3 中计算的标签是公共子字符串的长度。

【讨论】:

    【解决方案2】:

    我找到了我正在寻找这个问题的论文。这个想法与 David Eisenstat 提到的一个想法相似。实际上我不需要连接两个字符串并且...,我可以构建第一个字符串的后缀树,然后在 previos 树上构建第二个字符串的后缀树。这意味着当我遍历前一棵树以找到 secons 字符串的方法时,我可以找到显示公共子字符串的公共路径。

    http://www.ncbi.nlm.nih.gov/pubmed/23349213

    【讨论】:

      【解决方案3】:

      是的,您可以相对容易地做到这一点,这称为动态编程。 创建一个布尔二维表,你的第一个维度是你的 str1,你的第二个维度是 s​​tr2。将所有常用数字设置为真。完成 bolean 2D 表后,沿对角线迭代并找到 true 的最大计数。

      【讨论】:

      • 这个程序的时间复杂度和内存使用量是 o(n^2) 我需要一些更高效的算法。特别是因为在我的情况下,一个字符串太长(假设 1000000 个字符)而另一个更小。那么这个表是如此稀疏和内存腰部。如果我决定用链接列表的想法来实现它,那么时间复杂度应该是另一个问题。但到目前为止,这是最好的主意,谢谢。
      • 首先。我没有写,也没有提出任何“程序”。我刚刚向您展示了如何潜在地解决您的问题。其次,在有人回复您之后开始添加之前,请首先详细说明您的所有要求。最后,我建议您阅读动态编程的工作原理。它的你的程序将在效率方面产生影响
      猜你喜欢
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多