最長(zhǎng)公共子序列問(wèn)題

假設(shè)有兩個(gè)序列S1[1...m]和S2[1...n]丹允,需要尋找它們之間的一個(gè)最長(zhǎng)公共子序列。
例如铲球,假定我們有如下兩個(gè)序列:
S1:I N T H E B E G I N N I N G
S2:A L L T H I N G S A R E L O S T
則S1和S2的一個(gè)最長(zhǎng)公共子序列為THING。又如:
S1:A B C B D A B
S2:B D C A B A
則S1和S2的一個(gè)最長(zhǎng)公共子序列為BCBA。
這里需要注音的是箱沦,一個(gè)子序列不一定必須是連續(xù)的,中間可以被其他字符分開雇庙。最長(zhǎng)公共子序列不一定只有一個(gè)谓形,而我們要尋找的是其中一個(gè)。
設(shè)c[i, j] = LCS(S1[1...i], S2[1...j]) 状共,表示S1[1...i]和S2[1...j]的最長(zhǎng)子序列套耕。那么問(wèn)題的解為c[m, n]。
仔細(xì)觀察我們可以知道:
如果S1[i] = S2[j]峡继,那么c[i, j] = c[i-1, j-1] + 1冯袍,
如果S1[i] ≠ S2[j],那么c[i, j] = max{c[i-1, j], c[i, j-1}(證明略)碾牌。那么我們就將原問(wèn)題分解為相似的子問(wèn)題康愤。而子問(wèn)題很多是重復(fù)的,所以我們將子問(wèn)題的結(jié)果存放到表中舶吗,防止重復(fù)計(jì)算征冷。
最長(zhǎng)公共子序列的Python代碼如下:

#!/usr/bin/python
# -*- coding: utf8 -*-
 
S1 = ['I', 'T', 'E', 'I', 'N', 'G']
S2 = ['T', 'I', 'N', 'G', 'E']
 
#后面幾組供測(cè)試使用
#S1 = ['A', 'N', 'T', 'H']
#S2 = ['A', 'L', 'N', 'T']
 
#S1 = ['I', 'N', 'T', 'H', 'E', 'B', 'E', 'G']
#S2 = ['A', 'L', 'L', 'T', 'H', 'I', 'N', 'G']
 
#S1 = ['A', 'B', 'C', 'B', 'D', 'A', 'B']
#S2 = ['B', 'D', 'C', 'A', 'B', 'A']
 
#存儲(chǔ)結(jié)果的數(shù)組,c[i+1, j+1] = LCS(S1[0...i], S2[0...j])誓琼,0<=i<m检激,0<=j<n
c = [[0 for col in range(len(S2) + 1)] for row in range(len(S1) + 1)]
#用于構(gòu)造最優(yōu)解肴捉,b[i][j]指向一個(gè)表項(xiàng),這個(gè)表項(xiàng)對(duì)應(yīng)于在計(jì)算c[i][j]時(shí)所選擇的最優(yōu)子問(wèn)題的解
b = [[0 for col in range(len(S2))] for row in range(len(S1))]
 
#初始化c數(shù)組
for i in range(len(c)):     
    c[i][0] = 0
for j in range(len(c[0])):
    c[0][j] = 0
    
##初始化b數(shù)組
#for i in range(len(S1)):
#    b1 = []
#    for j in range(len(S2)):
#        b1.append(0)
#    b.append(b1) 
 
#使用動(dòng)態(tài)規(guī)則計(jì)算S1和S2的最長(zhǎng)子序列
#返回最長(zhǎng)子序列的長(zhǎng)度
def LCS(S1, S2):
    for i in range(len(S1)):
        for j in range(len(S2)):
            if S1[i] == S2[j]:
                c[i + 1][j + 1] = c[i][j] + 1
                b[i][j] = "↖"
            elif c[i][j + 1] >= c[i + 1][j]:
                c[i + 1][j + 1] = c[i][j + 1]
                b[i][j] = "↑"
            else:
                c[i + 1][j + 1] = c[i + 1][j]
                b[i][j] = "←"
    return c[len(S1)][len(S2)]
 
#根據(jù)表b構(gòu)造出一個(gè)LCS 
def print_LCS(b, X, i, j):
    if i == -1 or j == -1:
        return 
    if b[i][j] == "↖" :
        print_LCS(b, X, i-1, j-1)
        print X[i]
    elif b[i][j] == "↑":
        print_LCS(b, X, i-1, j)
    else:
        print_LCS(b, X, i, j-1)
 
print(LCS(S1, S2))
print_LCS(b, S1, len(S1) - 1, len(S2) - 1)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叔收,一起剝皮案震驚了整個(gè)濱河市齿穗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饺律,老刑警劉巖窃页,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異复濒,居然都是意外死亡脖卖,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門巧颈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)畦木,“玉大人,你說(shuō)我怎么就攤上這事洛二〔雠” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵晾嘶,是天一觀的道長(zhǎng)妓雾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)垒迂,這世上最難降的妖魔是什么械姻? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮机断,結(jié)果婚禮上楷拳,老公的妹妹穿的比我還像新娘。我一直安慰自己吏奸,他們只是感情好欢揖,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奋蔚,像睡著了一般她混。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泊碑,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天坤按,我揣著相機(jī)與錄音,去河邊找鬼馒过。 笑死臭脓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腹忽。 我是一名探鬼主播来累,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼砚作,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了佃扼?” 一聲冷哼從身側(cè)響起偎巢,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兼耀,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體求冷,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘤运,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匠题。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拯坟。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖韭山,靈堂內(nèi)的尸體忽然破棺而出郁季,到底是詐尸還是另有隱情,我是刑警寧澤钱磅,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布梦裂,位于F島的核電站,受9級(jí)特大地震影響盖淡,放射性物質(zhì)發(fā)生泄漏年柠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一褪迟、第九天 我趴在偏房一處隱蔽的房頂上張望冗恨。 院中可真熱鬧,春花似錦味赃、人聲如沸掀抹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)傲武。三九已至,卻和暖如春另凌,著一層夾襖步出監(jiān)牢的瞬間谱轨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工吠谢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留土童,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓工坊,卻偏偏與公主長(zhǎng)得像献汗,于是被迫代替她去往敵國(guó)和親敢订。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)罢吃。 張土汪:刷leetcod...
    土汪閱讀 12,748評(píng)論 0 33
  • 公共子序列與公共子串不同在于子序列不要求連續(xù)楚午。利用兩個(gè)二維數(shù)組進(jìn)行求解,c數(shù)組負(fù)責(zé)存值尿招,求得子序列最大長(zhǎng)度矾柜,即途中...
    icecrea閱讀 3,790評(píng)論 0 1
  • 動(dòng)態(tài)規(guī)劃(Dynamic Programming) 本文包括: 動(dòng)態(tài)規(guī)劃定義 狀態(tài)轉(zhuǎn)移方程 動(dòng)態(tài)規(guī)劃算法步驟 最長(zhǎng)...
    廖少少閱讀 3,296評(píng)論 0 18
  • 問(wèn)題描述: 求兩個(gè)字符序列的公共最長(zhǎng)子序列。 最長(zhǎng)公共子串 在回到子序列問(wèn)題之前就谜,先來(lái)了解一下子串的問(wèn)題怪蔑。例如,H...
    我沒(méi)有三顆心臟閱讀 1,457評(píng)論 0 1
  • 我是日記星球的114號(hào)星寶寶,這是我的第69篇原創(chuàng)日記虹统。 我一直都想開一家對(duì)貧困人群免費(fèi)的養(yǎng)老院弓坞,一家醫(yī)院。 20...
    書香天使閱讀 253評(píng)論 0 2