問題描述:給定兩個不為空的字串或數列,求出這兩個字串或序列最長的公共子串行。
思路:最長公共子串行和最長公共子串概念不同,子串要求必須為連續,而子串行則不要求連續性,只需保證公共子串行每乙個字元的先後順序在兩個字串或序列中一致即可。因此,我們在公共子串的基礎上做一定修改,遞推公式作如下改變:
f (i
,j)=
0 & \text a[i]\not=b[j]\cap i=0 \ \cap \ j = 0\\1 & \text a[i]=b[j]\cap i=0 \ \cap \ j = 0\\max(f(i, j-1),f(i-1, j)) & \text a[i]\not=b[j]\\f(i-1, j-1) +1 & \text a[i]=b[j] \end
f(i,j)
=⎩⎪⎪
⎪⎨⎪⎪
⎪⎧0
1max
(f(i
,j−1
),f(
i−1,
j))f
(i−1
,j−1
)+1
a[i]
=b
[j]∩
i=0∩
j=0a
[i]=
b[j]
∩i=0
∩j=0
a[i]
=b
[j]a
[i]=
b[j]
同最長公共子串的主要區別是,最長公共子串行在當前位置元素不相等時,會累積之前元素匹配結果的最大值,而不是歸零。下面給出實現**:
class solution:
def __init__
(self, a, b)
: self.a = a
self.b = b
self.matrix =
self.seq =
self.
lcsequence
(self.a, self.b)
def lcsequence
(self, a, b)
: lengtha =
len(a)
lengthb =
len(b)
longest =
0if lengtha ==
0 or lengthb ==0:
return
for i in range
(lengtha)
: self.matrix.([
])for j in range
(lengthb)
:if a[i]
== b[j]
:if i ==
0 or j ==0:
self.matrix[i].(
1)else
: self.matrix[i]
.(self.matrix[i -1]
[j -1]
+1)else
:if i ==
0 and j ==0:
self.matrix[i].(
0)elif i ==0:
self.matrix[i]
.(self.matrix[i]
[j-1])
elif j ==0:
self.matrix[i]
.(self.matrix[i-1]
[j])
else
: self.matrix[i].(
max(self.matrix[i-1]
[j], self.matrix[i]
[j-1])
)if self.matrix[i]
[j]> longest:
longest = self.matrix[i]
[j] self.
sequences()
print
(longest)
print
(self.seq)
def sequences
(self):if
len(self.matrix)==0
:return
self.
search
(self.matrix,
len(self.a)-1
,len
(self.b)-1
) def search
(self, matrix, i, j, record=
):if matrix[i]
[j]==0:
ifisinstance
(self.a, list):if
list
(reversed
(record)
) not in self.seq:
self.seq.
(list
(reversed
(record)))
return
elif isinstance
(self.a, str):if
"".join
(reversed
(record)
) not in self.seq:
self.seq.(""
.join
(reversed
(record)))
return
elif i==
0 or j==0:
record.
(self.a[i]
if i==
0else self.b[j])if
isinstance
(self.a, list):if
list
(reversed
(record)
) not in self.seq:
self.seq.
(list
(reversed
(record)))
elif isinstance
(self.a, str):if
"".join
(reversed
(record)
) not in self.seq:
self.seq.(""
.join
(reversed
(record)))
del record[-1
]return
if matrix[i]
[j]== matrix[i]
[j-1]:
self.
search
(matrix, i, j-
1, record)
if matrix[i]
[j]== matrix[i-1]
[j]:
self.
search
(matrix, i-
1, j, record)
if matrix[i]
[j]== matrix[i-1]
[j-1]+
1 and self.a[i]
== self.b[j]
: record.
(self.a[i]
) self.
search
(matrix, i-
1, j-
1, record)
del record[-1
]return
if __name__ ==
'__main__'
: sol =
solution
("13456778"
,"357486782"
)
上述**輸出為最長公共子串行長度,以及符合這一長度的所有結果。輸出結果如下:
根據結果對比實際答案,我們的演算法基本正確。
演算法 最長公共子串行
好久沒做演算法題了,現在發現自己的演算法能力非常薄弱,所以特意練練,順便做個筆記方便以後檢視。今天整理一下最長公共子串行,最長公共子串行的問題常用於解決字串的相似度,是乙個非常實用的演算法,作為碼農,此演算法是我們的必備基本功。最長公共子串行,是指兩個字串可具有的長度最大的公共的子串行。聽著好像有點...
演算法 最長公共子串行
題目 給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。乙個字串的 子串行 是指這樣乙個新的字串 它是由原字串在不改變字元的相對順序的情況下刪除某些字元 也可以不刪除任何字元 後組成的新字串。例如,ace 是 abcde 的子串行,但 aec 不是 abcde 的子串行...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...