description
給定兩個字串,返回兩個字串的最長公共子串行(不是最長公共子字串),可能是多個。
input
輸入第一行為用例個數, 每個測試用例輸入為兩行,一行乙個字串
output
如果沒有公共子串行,不輸出,如果有多個則分為多行,按字典序排序。
sample input 1
1
1a2bd3g4h56jk
23efg4i5j6k7
sample output 1
23g456k
23g45jk
題目解析
找到最長的公共子串行
若有多個,輸出所有的公共子串行
思路解析
根據狀態轉移方程構建dp陣列
根據dp陣列遞迴獲得所有的公共子串行
將公共子串行去重並排序 例子
```
a = "siufklhdcfkl"
b = "sadfliudklfh"
# 行為a ,列為b
```
dp陣列如下:shape(len(b)+1,len(a)+1),有b+1行,a+1列
如何遞迴?
從最後乙個節點開始,觀察dp陣列,首先明確
滿足dp[i - 1][j] == dp[i][j - 1] != dp[i][j]-1的格仔才是要輸出的字元,因為這個字元一定是兩個陣列中的相同字元.
如: 5 4
5 6 4 5
若 dp[i - 1][j] == dp[i][j - 1] == dp[i][j]:
如: 6
6 6
則向左和向上同時遞迴
若 dp[i - 1][j] > dp[i][j - 1]
如 5
6 6則向左遞迴
若 dp[i][j - 1] > dp[i][j]
如 6
5 6則向上遞迴
若dp[i - 1][j] == dp[i][j - 1] != dp[i][j]:
如:5 5
5 6
此時滿足條件,記錄字串,並則向斜上方遞迴
**實現# import numpy as np
# 列印陣列結構
# def printdp(dp):
# dp2 = np.array(dp)
# dp2 = np.c_[["*"] + list(b), dp2]
# print(len(dp2[0]))
# print(len(["*", "*"] + list(a)))
# dp2 = np.insert(dp2, 0, ["*", "*"] + list(a), axis=0)
# print(dp2.shape)
# print(dp2)
# return dp2
defget_path
(i, j, res, l)
:# *** = np.array(dp) # 可以debug觀察陣列結構
if dp[i]
[j]==0:
if res[::
-1]!=
"":::
-1])
# print(res[::-1])
return
if dp[i -1]
[j]== dp[i]
[j -1]
:if dp[i -1]
[j]== dp[i]
[j -1]
== dp[i]
[j]:
get_path(i -
1, j, res, l)
get_path(i, j -
1, res, l)
else
: get_path(i -
1, j -
1, res +
str(a[j -1]
), l)
elif dp[i -1]
[j]> dp[i]
[j -1]
: get_path(i -
1, j, res, l)
else
: get_path(i, j -
1, res, l)
if __name__ ==
'__main__'
: case_num =
[int
(x)for x in
input()
.strip(
).split(
" ")][
0]for i in
range
(case_num)
: a =
input()
.strip(
) b =
input()
.strip(
) dp =[[
0]*(
len(a)+1
)for _ in
range
(len
(b)+1)
]# b+1行 a+1列,初始化為0
# 構建dp陣列
for i in
range
(len
(b))
:for j in
range
(len
(a))
:if b[i]
== a[j]
: dp[i +1]
[j +1]
= dp[i]
[j]+
1else
: dp[i +1]
[j +1]
=max
(dp[i +1]
[j], dp[i]
[j +1]
) l_arr =
# dp2 = printdp(dp)
# 遞迴尋找子串行
get_path(
len(b)
,len
(a),
"", l_arr)
#去重 l_arr =
list
(set
(l_arr)
) l_arr.sort()if
len(l_arr)==0
:print()
for x in l_arr:
print
(x)
演算法 最長公共子串行
好久沒做演算法題了,現在發現自己的演算法能力非常薄弱,所以特意練練,順便做個筆記方便以後檢視。今天整理一下最長公共子串行,最長公共子串行的問題常用於解決字串的相似度,是乙個非常實用的演算法,作為碼農,此演算法是我們的必備基本功。最長公共子串行,是指兩個字串可具有的長度最大的公共的子串行。聽著好像有點...
演算法 最長公共子串行
題目 給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。乙個字串的 子串行 是指這樣乙個新的字串 它是由原字串在不改變字元的相對順序的情況下刪除某些字元 也可以不刪除任何字元 後組成的新字串。例如,ace 是 abcde 的子串行,但 aec 不是 abcde 的子串行...
python 最長公共子串行
usr bin env python3 coding utf 8 最長公共子串行 fish fosh fsh def findlongestsubstring source,dest 輸入值,要比較的值 inlen len source outlen len dest target cell 0 f...