我正在通过this paper来计算两个字符串之间不同的公共子序列的数量,这些子序列描述了DP方法来做同样的事情。现在,当有两个以上的字符串必须找到不同的公共子序列的数量时,可能需要采用与此不同的方法。我想要的是,这个任务是否可以在时间复杂度下实现,而不是指数级,以及如何实现?
答案 0 :(得分:1)
如果您的字母大小为k
,且m
字符串的大小最多为n
,那么(假设所有单独的数学运算都为O(1)
)此问题是可以在最多O(k nm+1)
和内存O(k nm)
及时动态编程解决。这些并不紧张,在实践中,性能和记忆应该明显优于那些。但是在使用长字符串的实践中,你最终需要大整数运算,这将使数学运算不是O(1)
。它仍然是多项式。
这是一个不幸令人困惑的句子中的伎俩。我们想要建立一系列的表列表,对于每个可能的子序列长度以及从每个字符串中选择一个字符副本的每组方法,不同子序列的数量是每个字符串中的最小表达式在所选择的结尾处结束点。如果我们这样做,那么所有这些值的总和就是我们的最终答案。
以下是如何操作的概述(您可以在不理解上述说明的情况下进行操作)。
对于每个字符串,构建一个转换表映射(字符串中的位置,字符)到该字符的下一次出现的位置。表格应从第一个字符之前的位置0开始。你可以使用-1来运行字符串的结尾。
创建一个数据结构,该结构将与您拥有的字符串数量相同的整数列表映射到另一个整数。这将是固定长度的子序列的计数,其中每个字符串中的最短表示在该组位置处结束。
作为唯一值(0, 0, ..., 0) -> 1
插入,以表示长度为0的1个子序列,并且每个字符串中的最短表示在开始时结束。
将公共子序列的总数设置为0.
虽然该地图不为空:
将该地图中的值之和添加到公共子序列的总数中。
创建第二个相同类型的地图,没有数据。
对于第一张地图中的每个键/值对:
对于字母表中的每个可能字符:
通过获取每个字符串,查看位置,然后获取该字符的下一个位置,构造一个新的整数向量作为新键。当然,如果你跑掉了字符串的末尾,那么就要打破循环。
如果该键不在您的第二张地图中,请将其插入值为0。
使用当前地图中的当前值增加第二个地图中该键的值。 (基本上添加刚刚进行了这种最小字符转换的子序列的数量。)
将第二个数据结构复制到第一个数据结构。
现在所有字符串中共同的不同子序列的总数应该是正确的。