给出一个多项式时间算法,该算法将三个字符串A,B和C作为输入,并返回最长的序列S,它是A,B和C的子序列。
答案 0 :(得分:3)
让dp[i, j, k] = longest common subsequence of prefixes A[1..i], B[1..j], C[1..k]
我们有:
dp[i, j, k] = dp[i - 1, j - 1, k - 1] + 1 if A[i] = B[j] = C[k]
max(dp[i - 1, j, k], dp[i, j - 1, k], dp[i, j, k - 1]) otherwise
与2d案例类似,但您有3个维度。复杂性为O(len A * len B * len C)
。
答案 1 :(得分:2)
这是Python中用于任意数量序列的解决方案。您可以使用它来测试2D,3D案例的解决方案。它紧跟Wikipedia's algorithm:
#!/usr/bin/env python
import functools
from itertools import starmap
@memoize
def lcs(*seqs):
"""Find longest common subsequence of `seqs` sequences.
Complexity: O(len(seqs)*min(seqs, key=len)*reduce(mul,map(len,seqs)))
"""
if not all(seqs): return () # at least one sequence is empty
heads, tails = zip(*[(seq[0], seq[1:]) for seq in seqs])
if all(heads[0] == h for h in heads): # all seqs start with the same element
return (heads[0],) + lcs(*tails)
return max(starmap(lcs, (seqs[:i]+(tails[i],)+seqs[i+1:]
for i in xrange(len(seqs)))), key=len)
def memoize(func):
cache = {}
@functools.wraps(func)
def wrapper(*args):
try: return cache[args]
except KeyError:
r = cache[args] = func(*args)
return r
return wrapper
注意:没有记忆,它是一个指数算法(wolfram alpha):
$ RSolve[{a[n] == K a[n-1] + K, a[0] = K}, a[n], n]
a(n) = (K^(n + 1) - 1) K/(K - 1)
其中K
== len(seqs)
和n
== max(map(len, seqs))
>>> lcs("agcat", "gac")
('g', 'a')
>>> lcs("banana", "atana")
('a', 'a', 'n', 'a')
>>> lcs("abc", "acb")
('a', 'c')
>>> lcs("XMJYAUZ", "MZJAWXU")
('M', 'J', 'A', 'U')
>>> lcs("XMJYAUZ")
('X', 'M', 'J', 'Y', 'A', 'U', 'Z')
>>> lcs("XMJYAUZ", "MZJAWXU", "AMBCJDEFAGHI")
('M', 'J', 'A')
>>> lcs("XMJYAUZ", "MZJAWXU", "AMBCJDEFAGUHI", "ZYXJAQRU")
('J', 'A', 'U')
>>> lcs() #doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
ValueError:
>>> lcs(*"abecd acbed".split())
('a', 'b', 'e', 'd')
>>> lcs("acd", lcs("abecd", "acbed"))
('a', 'd')
>>> lcs(*"abecd acbed acd".split())
('a', 'c', 'd')
答案 2 :(得分:1)
你所要做的就是谷歌“最长的后续”。
这是顶部链接:http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
如果您对此有任何特殊问题,请在此处询问,最好提出更具体的问题。