最長公共子串行問題

2021-09-29 14:52:43 字數 3180 閱讀 3937

乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列。給定兩個序列a

aa和b

bb找出兩個序列的最長公共子串行。

分兩行分別輸入字串a

aa和bbb。

輸出分為兩行,第一行輸出乙個整數,表示最長公共子串行的長度,第二行以字串的形式輸出最長公共子串行。

gksidertefxsxsepbnwb

sdhfirekdjnfdrwesdcxxhi

7sidrexx

區域性的最長公共子串行一定是全域性的最長公共子串行的子集,所以區域性的最長公共子串行可以被全域性的最長公共子串行進行繼承或者拓展。

我們使用lcs

(p,q

)lcs(p,q)

lcs(p,

q)表示序列p

pp和q

qq的最長公共子串行。現在有兩個序列ai=

,bj=

a_i=\,b_j=\

ai​=,b

j​=,當ai=

bj=s

a_i=b_j=s

ai​=bj

​=s時,說明s

ss一定是最長公共子串行中的乙個元素即s∈l

cs(a

i,bj

)s\in lcs(a_i,b_j)

s∈lcs(

ai​,

bj​)

,並且是對lcs

(ai−

1,bj

−1

)lcs(a_,b_)

lcs(ai

−1​,

bj−1

​)的乙個拓展即lcs

(ai,

bj)=

lcs(

ai−1

,bj−

1)

∪lcs(a_i,b_j)=lcs(a_,b_)\cup\

lcs(ai

​,bj

​)=l

cs(a

i−1​

,bj−

1​)∪

;當a i≠

bj

a_i\not=b_j

ai​​=

bj​時,說明lcs

(ai,

bj

)lcs(a_i,b_j)

lcs(ai

​,bj

​)在l cs

(ai,

bj−1

)lcs(a_i,b_)

lcs(ai

​,bj

−1​)

或l cs

(ai−

1,bj

)lcs(a_,b_j)

lcs(ai

−1​,

bj​)

中即l cs

(ai,

bj)=

max⁡(l

cs(a

i,bj

−1),

lcs(

ai−1

,bj)

)lcs(a_i,b_j)=\max(lcs(a_i,b_),lcs(a_,b_j))

lcs(ai

​,bj

​)=max(l

cs(a

i​,b

j−1​

),lc

s(ai

−1​,

bj​)

)。通過上面的推理我們知道此問題滿足最優子結構和重疊子問題的性質,因此可以使用動態規劃解決。由推論可以得出關於計算最長公共子串行長度的狀態轉移方程:

t [i

][j]

=0&&i=0\\ 0&&j=0\\ t[i-1][j-1]+1&&a_i=b_j\\ \max(t[i][j-1],t[i-1][j])&&a_i\not=b_j \end \right.

t[i][j

]=⎩⎪

⎪⎨⎪⎪

⎧​00

t[i−

1][j

−1]+

1max(t

[i][

j−1]

,t[i

−1][

j])​

​i=0

j=0a

i​=b

j​ai

​​=

bj​​

#include

#include

#include

#include

using

namespace std;

intmain()

else}}

cout << t[a.

size()

][b.

size()

]<< endl;

return0;

}

#include

#include

#include

#include

using

namespace std;

intmain()

; string a,b;

cin >> a;

cin >> b;

vector

>

t(a.

size()

+1,vector

(b.size()

+1))

;///申請記憶體空間,並將其中全部填入0

vector

>

s(a.

size()

+1,vector

(b.size()

+1))

;///申請記憶體空間,用於記錄尋找最長公共子串行的過程

for(size_t i=

0;isize()

;i++

)else

else}}

} cout << t[a.

size()

][b.

size()

]<< endl;

stack<

char

> p;

///建立棧

for(size_t i=a.

size()

,j=b.

size()

;i&&j;)}

while

(!p.

empty()

) cout << endl;

return0;

}

最長公共子串行問題

給定整數a1,a2,an 可能有負值 求連續子串行和的最大值。為方便起見,如果所有整數都為負值,則最大子串行和為0 這是個顯而易見的方法,幾乎每個人在第一眼看到該問題都能夠想出來的方法。就是將所有的子串行找出來,然後求和最大的乙個。如果序列足夠大,該方法的效率可想而知。如下 include incl...

最長公共子串行問題

最長公共子串行問題很早就在很多論壇上見過,前幾天看到乙個人發了一篇帖子,心血來潮就去看演算法導論上的動態規劃部分,關於這個問題不再細述,直接貼c 實現的具體 了。做大公共子串行問題 pragma once include using std string define over 1 書中使用箭頭符號...

最長公共子串行問題

問題描述 字串行的子串行是指從給定字串行中隨意地 不一定連續 去掉若干個字元 可能乙個也不去掉 後所形成的字串行。令給定的字串行x x0,x1,xm 1 序列y y0,y1,yk 1 是x的子串行,存在x的乙個嚴格遞增下標序列,使得對所有的j 0,1,k 1,有xij yj。例如,x abcbdab...