如何求指数时间内的最长公共子序列?
我可以使用动态编程以正确的方式做到这一点,但我不知道如何在指数时间内做到这一点。
我正在寻找两个字符串之间最大的公共子序列。 注意:我的意思是子序列而不是子串,组成序列的符号不必是连续的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我可以使用动态编程以正确的方式做到这一点,但我不知道如何在指数时间内做到这一点。
我正在寻找两个字符串之间最大的公共子序列。 注意:我的意思是子序列而不是子串,组成序列的符号不必是连续的。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
只需用递归调用替换动态编程代码中表中的查找即可。换句话说,只需实现 LCS 问题的递归公式:
编辑
在伪代码中(实际上几乎是 python):
Just replace the lookups in the table in your dynamic programming code with recursive calls. In other words, just implement the recursive formulation of the LCS problem:
EDIT
In pseudocode (almost-python, actually):
假设您有两个长度为
n
的字符串a
和b
。最长公共子序列将是字符串a
中最长的子序列,同时也出现在字符串b
中。因此,我们可以迭代
a
中所有可能的子序列,并查看它在b
中。一个高级伪代码是:
Let's say you have two strings
a
andb
of lengthn
. The longest common subsequence is going to be the longest subsequence in stringa
that is also present in stringb
.Thus we can iterate through all possible subsequences in
a
and see it is inb
.A high-level pseudocode for this would be:
字符串A和字符串B。一个递归算法,也许它很幼稚,但很简单:
看看A的第一个字母。这要么是一个共同的序列,要么不是。当考虑“not”选项时,我们修剪掉第一个字母并递归调用。当考虑“处于公共序列中”选项时,我们也会将其修剪掉,并且还会从 B 的开头一直修剪到 B 中的相同字母(包括 B 中的相同字母)。一些伪代码:
您可以从它开始,然后通过以下方式进行优化记住迄今为止找到的最长子序列,然后在当前函数无法击败该子序列时(即当 min(len(A), len(B))+len_subsequence_so_far 小于找到的最长子序列时提前返回)所以 远的。
String A and String B. A recursive algorithm, maybe it's naive but it is simple:
Look at the first letter of A. This will either be in a common sequence or not. When considering the 'not' option, we trim off the first letter and call recursively. When considering the 'is in a common sequence' option we also trim it off and we also trim off from the start of B up to, and including, the same letter in B. Some pseudocode:
You could start with that and then optimize by remembering the longest subsequence found so far, and then returning early when the current function cannot beat that (i.e. when
min(len(A), len(B))+len_subsequence_so_far
is smaller than the longest length found so far.本质上,如果您不使用动态编程范例,您就会达到指数时间。这是因为,如果不存储部分值,您将多次重新计算部分值。
Essentially if you don't use dynamic programming paradigm - you reach exponential time. This is because, by not storing your partial values - you are recomputing the partial values multiple times.
为了实现指数时间,生成两个数组的所有子序列并将每个子序列相互比较就足够了。如果匹配两个相同的长度,请检查它们的长度是否大于当前的最大值。伪代码是:
这绝对不是最佳。它甚至不尝试。然而问题是关于非常低效的算法,所以我提供了一个。
To achieve exponential time it's enough to generate all subsequences of both arrays and compare each one with each other. If you match two that are identical check if their length is larger then current maximum. The pseudocode would be:
It's absolutely not optimal. It doesn't even try. However the question is about the very inefficient algorithm so I've provided one.