[Python]獲取2個字串的最長公共子串
阿新 • • 發佈:2018-12-29
原創文章,歡迎轉載。轉載請註明:轉載自 祥的部落格
原文連結:https://blog.csdn.net/humanking7/article/details/84645055
文章目錄
1.問題引出
我下載了一些英語資料,這些資料的命名還好,但是就是沒有用資料夾歸檔,整體感覺很亂,所以打算要將他們用資料夾分類。
計劃是這樣的:
- 查詢所有
pdf
用pdf名字
建立資料夾,並將對應的pdf
檔案,移入資料夾
中; - 查詢與
pdf名字
最接近的MP3檔案
,並將其移入對應的資料夾
中。
看到明顯是一本書的文字
和音訊資料
:
- 文字:
黑貓英語名著3級 02 Alic's Adventures In Wonderland 艾麗絲漫遊奇境記.pdf
- 音訊:
艾麗絲漫遊奇境記 Alic_s Adventures In Wonderland 01.mp3
可以發現,他們都有相同的子字串
,所以先要處理找兩個字串最長公共子串的問題
。
2. 原始碼及測試結果
2.1. 程式原始碼
def getMaxCommonSubstr(s1, s2):
# 求兩個字串的最長公共子串
# 思想:建立一個二維陣列,儲存連續位相同與否的狀態
len_s1 = len(s1)
len_s2 = len(s2)
# 生成0矩陣,為方便後續計算,多加了1行1列
# 行: (len_s1+1)
# 列: (len_s2+1)
record = [[0 for i in range(len_s2+1)] for j in range(len_s1+1)]
maxNum = 0 # 最長匹配長度
p = 0 # 字串匹配的終止下標
for i in range(len_s1):
for j in range(len_s2):
if s1[i] == s2[j]:
# 相同則累加
record[i+1][j+1] = record[i][j] + 1
if record[i+1][j+1] > maxNum:
maxNum = record[i+1][j+1]
p = i # 匹配到下標i
# 返回 子串長度,子串
return maxNum, s1[p+1-maxNum : p+1]
def printMatrixList(li):
# 列印多維list
row = len(li)
col = len(li[0])
for i in range(row):
for j in range(col):
print(li[i][j], end=' ')
print('')
if __name__ == "__main__":
# s1="黑貓英語名著3級 02 Alic's Adventures In Wonderland 艾麗絲漫遊奇境記.pdf"
# s2="艾麗絲漫遊奇境記 Alic_s Adventures In Wonderland 01.mp3"
s1='abcdef'
s2='bcxdef'
[lenMatch,strMatch] = getMaxCommonSubstr(s1,s2)
print('子串: ', strMatch)
print('子串長度: ', lenMatch)
2.2. 測試結果
# 如果資料是`abcdef`等
子串: def
子串長度: 3
# 如果資料是`艾麗絲`等
子串: s Adventures In Wonderland
子串長度: 27
3. 分析
對於測試字串為:
s1='abcdef'
s2='bcxdef'
明顯看出有2
個公共子串,bc
和def
,上述的方法就是用2個字串
各自的長度建立了一個矩陣,矩陣數值初始都是0
,一個字元一個字元的進行對比,如果字元相等
,就在左上對角線元素的數值上加一
(如下面所示)。
假設字串長度分別為n
和m
,則建立這個矩陣的時候,演算法複雜度為O(nm)
,查詢最大子串的演算法複雜度為O(nm)
,整體演算法的複雜度為2O(nm)
。
理論上,可以把建立矩陣和查詢放在一起,這樣就會優化許多,等我閒了再搞吧,先完成主要目標。
0 b c x d e f
a 0 0 0 0 0 0
b 1 0 0 0 0 0
c 0 2 0 0 0 0
d 0 0 0 1 0 0
e 0 0 0 0 2 0
f 0 0 0 0 0 3
4. Next
最終不要忘了 初心:
[Python]將MP3和PDF按名字分類歸檔到各自資料夾 : https://blog.csdn.net/humanking7/article/details/84663012
以上,Enjoy~