我有一对字符串,例如:abcabcabc
和abcxxxabc
以及公共子字符串对列表(LCSP),在这种情况下,LCSP是6对,因为三个abc
在第一个字符串映射到第二个字符串中的两个abc
。现在我需要找到最长的有效(递增)对的序列,在这种情况下有三个同样长的解:0:0,3:6; 0:0,6:6; 3:0,6:6
(这些数字是原始字符串中每对的起始位置,子串的长度是3作为“abc”的长度。我将其称为最长子串对序列或LSPQ。 (Q不要混淆字符串和序列)
以下是此示例的LCSP:
LCSP('abcabcabc', 'abcxxxabc') =
[ [ 6, 6, 3 ],
[ 6, 0, 3 ],
[ 3, 6, 3 ],
[ 0, 6, 3 ],
[ 3, 0, 3 ],
[ 0, 0, 3 ] ]
LSPQ(LCSP('abcabcabc', 'abcxxxabc'), 0, 0, 0) =
[ { a: 0, b: 0, size: 3 }, { a: 3, b: 6, size: 3 } ]
现在我用蛮力递归尝试所有组合。所以我被限制在大约25对,否则它是不切实际的。 Size=[10,15,20,25,26,30], Time ms = [0,15,300,1000,2000,19000]
有没有办法在线性时间或至少不是二次复杂度中这样做,以便可以使用更长的输入LCSP(公共子串对列表)。
此问题类似于“最长公共子序列”,但不完全相同,因为输入不是两个字符串,而是按其长度排序的公共子字符串列表。所以我不知道在哪里寻找现有的解决方案,即使它们存在。
这是我的特定代码(JavaScript):
function getChainSize(T) {
var R = 0
for (var i = 0; i < T.length; i++) R += T[i].size
return R
}
function LSPQ(T, X, Y, id) {
// X,Y are first unused character is str1,str2
//id is current pair
function findNextPossible() {
var x = id
while (x < T.length) {
if (T[x][0] >= X && T[x][1] >= Y) return x
x++
}
return -1
}
var id = findNextPossible()
if (id < 0) return []
var C = [{a:T[id][0], b:T[id][1], size:T[id][2] }]
// with current
var o = T[id]
var A = C.concat(LSPQ(T, o[0]+o[2], o[1]+o[2], id+1))
// without current
var B = LSPQ(T, X, Y, id+1)
if (getChainSize(A) < getChainSize(B)) return B
return A
}