Python使用回溯法子集樹模板獲取最長公共子序列(LCS)的方法
本文實(shí)例講述了Python使用回溯法子集樹模板獲取最長公共子序列(LCS)的方法。分享給大家供大家參考,具體如下:
問題
輸入
第1行:字符串A
第2行:字符串B
(A,B的長度 <= 1000)
輸出
輸出最長的子序列,如果有多個(gè),隨意輸出1個(gè)。
輸入示例
belong
cnblogs
輸出示例
blog
分析
既然打算套用回溯法子集樹模板,那就要祭出元素-狀態(tài)空間分析大法。
以長度較小的字符串中的字符作為元素,以長度較大的字符串中的字符作為狀態(tài)空間,對(duì)每一個(gè)元素,遍歷它的狀態(tài)空間,其它的事情交給剪枝函數(shù)!??!
解x的長度不固定,xi表示字符串b中的序號(hào)。
在處理每一個(gè)元素時(shí),如果沒有一個(gè)狀態(tài)被選擇(cnblogs中沒一個(gè)字符被選取),那么程序無法去往下一個(gè)元素。
這確實(shí)是個(gè)不小的麻煩!??!思考了一天,終于想出辦法了:擴(kuò)充狀態(tài)空間,增加一個(gè)狀態(tài)q!如果元素選取了狀態(tài)q,它是合法的。但是,狀態(tài)q不加入解x內(nèi)?。?!
看一個(gè)直觀的圖:
至此,enjoy it!
代碼
'''最長公共子序列''' # 作者:hhh5460 # 時(shí)間:2017年6月3日 a = 'belong' b = 'cnblogs' x = [] # 一個(gè)解(長度不固定)xi是b中字符的序號(hào) X = [] # 一組解 best_x = [] # 最佳解 best_len = 0 # 最大子序列長度 # 沖突檢測(cè) def conflict(k): global n, x, X, a,b,best_len # 如果兩個(gè)字符不相等 if x[-1] < len(b) and a[k] != b[x[-1]]: return True # 如果兩個(gè)字符相等,但是相對(duì)于前一個(gè)在b中的位置靠前 if a[k] == b[x[-1]] and (len(x) >= 2 and x[-1] <= x[-2]): return True # 如果部分解的長度加上后面a剩下的長度,小于等于best_len if len(x) + (len(a)-k) < best_len: return True return False # 無沖突 # 回溯法(遞歸版本) def LCS(k): # 到達(dá)a中的第k個(gè)元素 global x, X,a,b,best_len,best_x #print(k, x) if k == len(a): # 超出最尾的元素 if len(x) > best_len: best_len = len(x) best_x = x[:] else: for i in range(len(b)+1): # 遍歷 狀態(tài)空間:0~len(b)-1,技巧:人為增加一種狀態(tài)len(b),表示改行沒有元素選取 if i==len(b): # 此狀態(tài)不放入解x內(nèi) LCS(k+1) else: x.append(i) if not conflict(k): # 剪枝 LCS(k+1) x.pop() # 回溯 # 根據(jù)一個(gè)解x,構(gòu)造最長子序列l(wèi)cs def get_lcs(x): global b return ''.join([b[i] for i in x]) # 測(cè)試 LCS(0) print(b) print(best_x) print(get_lcs(best_x))
效果圖
更多關(guān)于Python相關(guān)內(nèi)容可查看本站專題:《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python Socket編程技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
相關(guān)文章
Python利用pandas和matplotlib實(shí)現(xiàn)繪制柱狀折線圖
這篇文章主要為大家詳細(xì)介紹了如何使用?Python?中的?Pandas?和?Matplotlib?庫創(chuàng)建一個(gè)柱狀圖與折線圖結(jié)合的數(shù)據(jù)可視化圖表,感興趣的可以了解一下2023-11-11Python基礎(chǔ)教程之淺拷貝和深拷貝實(shí)例詳解
這篇文章主要介紹了Python基礎(chǔ)教程之淺拷貝和深拷貝實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07解決Python3 控制臺(tái)輸出InsecureRequestWarning問題
這篇文章主要介紹了解決Python3 控制臺(tái)輸出InsecureRequestWarning的問題 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07pytorch隨機(jī)采樣操作SubsetRandomSampler()
這篇文章主要介紹了pytorch隨機(jī)采樣操作SubsetRandomSampler(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07Python實(shí)現(xiàn)for循環(huán)倒序遍歷列表
這篇文章主要介紹了Python實(shí)現(xiàn)for循環(huán)倒序遍歷列表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05python實(shí)現(xiàn)FFT快速傅立葉變換算法案例
FFT(快速傅里葉變換)是計(jì)算DFT及其逆變換的一種算法,其基本思想是利用DFT的對(duì)稱性和周期性,通過分而治之的策略將DFT分解為更小的DFT,從而降低計(jì)算復(fù)雜度,FFT的算法步驟包括選擇分解、重新排序、蝶形運(yùn)算和逐層計(jì)算,在Python中2024-10-10