演算法 最長公共子串行 python

2021-09-29 09:31:11 字數 3548 閱讀 1191

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...