【问题标题】:how to find all the possible longest common subsequence from the same position如何从同一位置找到所有可能的最长公共子序列
【发布时间】:2013-05-22 02:35:11
【问题描述】:

我试图从多个固定长度字符串的相同位置找到所有可能的最长公共子序列(总共有 700 个字符串,每个字符串有 25 个字母)。最长的公共子序列必须包含至少 3 个字母并且属于至少 3 个字符串。所以如果我有:

String test1 = "abcdeug";
String test2 = "abxdopq";
String test3 = "abydnpq";
String test4 = "hzsdwpq";

我需要的答案是:

String[] Answer = ["abd", "dpq"];

我的一个问题是这需要尽可能快。我正在尝试用后缀树寻找答案,但是后缀树方法的解决方案是["ab","pq"]。后缀树只能从多个字符串中找到连续的子串。常见的最长公共子序列算法无法解决这个问题。 有谁知道如何以较低的时间成本解决这个问题? 谢谢

【问题讨论】:

  • 可能有多少个字符串?字符串数量和长度的上限是多少?
  • abdpdq 都没有出现在任何字符串中?它们怎么可能是子字符串?
  • “abd”出现在test1、test2和test3中,“dpq”出现在test2、test3和test4中
  • 共有700个字符串,每个字符串有25个字母

标签: suffix-tree string-comparison


【解决方案1】:

我建议您在尝试使用任何听起来可能会执行您想要的操作的算法之前,将其转换为一个众所周知的计算问题。

这是我的建议:将其转换为图形问题。对于字符串中的每个位置,您创建一组节点(一个用于集合中所有字符串中该位置的每个唯一字母......所以如果所有 700 个字符串在同一位置不同,则为 700 个节点)。一旦您为字符串中的每个位置创建了所有节点,您将通过您的字符串集查看两个位置共享超过 3 个相等连接的频率。在您的示例中,我们将首先查看位置 1 和 2,并看到三个字符串在位置 1 中包含“a”,在位置 2 中包含“b”,因此我们在第一组节点中的节点“a”之间添加有向边第二组节点中的图形和“b”(继续对所有位置对和这两个位置中的所有字母组合执行此操作)。您为每个职位组合执行此操作,直到您添加了所有必要的链接。

一旦你有了最终的图表,你必须寻找最长的路径;我建议在这里查看维基百科文章:Longest Path。在我们的例子中,我们将有一个有向无环图,您可以在线性时间内解决它!预处理应该是字符串位置数的二次方,因为我认为您的字母表是固定大小的。

P.S:你给我发了一封关于我正在研究的双聚类算法的电子邮件;它尚未发布,但将在今年某个时候提供(手指交叉)。不过感谢您的关注:)

【讨论】:

  • 谢谢 Katalyst。我的电子邮件是 txd866@gmail.com。我期待着你关于双聚类算法的论文
  • 亲爱的 Katalyst,我不知道您的电子邮件地址。我的电子邮件是 txd866@gmail.com。你能给我发一篇关于你正在研究的双聚类算法的文章吗?谢谢。
  • 您好,正如我上面提到的,这篇文章还没有发表!但是,一旦可用,我很乐意向您发送链接:)
  • 尊敬的 Katalyst,您发表的文章是关于使用最长路径方法进行双聚类的吗?请您给我发一篇关于您正在研究的双聚类算法的文章。我的电子邮件是 txd866@gmail.com。谢谢
【解决方案2】:

您可以尝试使用散列。
每个字符串最多有 25 个字符。这意味着它有 2^25 个子序列。你取每个字符串,计算所有 2^25 个哈希值。然后你加入所有字符串的所有哈希并计算其中至少包含 3 次。 为了获得这些子序列的长度,您不仅需要存储散列,还需要存储对 <hash, subsequence_pointer> 其中subsequence_pointer 确定该散列的子序列(最简单的方法是枚举所有字符串的所有散列并存储散列号)。
根据算法,最坏情况下的程序(700 个字符串,每个 25 个字符)将运行几分钟。

【讨论】:

  • 谢谢您的回答。但是您的方法时间和空间成本很高
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-16
  • 2015-06-23
  • 2011-03-01
  • 2021-11-04
相关资源
最近更新 更多