其他算法-LCS

LCS算法

LCS即Longest Common Subsequence:最长公共子序列;
一个序列S任意删除若干个字符后得到序列T,则T叫做S的子序列,假设现在有X和Y两个序列,两者最长的公共子序列即X,Y的LCS:
比如:13455和245576的LCS为455,acdfg和adfc的LCS为adf,注意LCS要和Longest Common Substring区分开,Longest Common Substring要求char连续不能分隔开;
如何找LCS
首先想到的是暴力穷举,令X的字符数量为m,Y的字符数量为n: X = { x 1 , . . . x m } X=\left \{ x_{1},...x_{m} \right \} X={x1,...xm} Y = { y 1 , . . . y n } Y=\left \{ y_{1},...y_{n} \right \} Y={y1,...yn}
X有 2 m 2^{m} 2m个不同子序列,Y有 2 n 2^{n} 2n个不同子序列,穷举的耗时为 O ( 2 m + n ) O(2^{m+n}) O(2m+n)
现在重新考虑: X i = { x 1 , . . . x i } X_{i}=\left \{ x_{1},...x_{i} \right \} Xi={x1,...xi}为X的前i个字符,简称X的i前缀, Y j Y_{j} Yj则称为Y的j前缀,LCS(X,Y)为: Z = { z 1 , . . . z k } Z=\left \{ z_{1},...z_{k} \right \} Z={z1,...zk}
如果 x m = y n x_{m}=y_{n} xm=yn,则LCS(X,Y)的最后一个字符必定为 x m x_{m} xm y n y_{n} yn,即 z k = x m = y n z_{k}=x_{m}=y_{n} zk=xm=yn,所以在这种情况下:
L C S ( X m , Y n ) = L C S ( X m − 1 , Y n − 1 ) + x m LCS(X_{m},Y_{n})=LCS(X_{m-1},Y_{n-1})+x_{m} LCS(Xm,Yn)=LCS(Xm1,Yn1)+xm
如果 x m ≠ y n x_{m}\neq y_{n} xm=yn,则 L C S ( X m , Y n ) LCS(X_{m},Y_{n}) LCS(Xm,Yn)要么等于 L C S ( X m , Y n − 1 ) LCS(X_{m},Y_{n-1}) LCS(Xm,Yn1),要么等于 L C S ( X m − 1 , Y n ) LCS(X_{m-1},Y_{n}) LCS(Xm1,Yn),即:
L C S ( X m , Y n ) = m a x { L C S ( X m − 1 , Y n ) , L C S ( X m , Y n − 1 ) } LCS(X_{m},Y_{n})=max\left \{ LCS(X_{m-1},Y_{n}),LCS(X_{m},Y_{n-1}) \right \} LCS(Xm,Yn)=max{LCS(Xm1,Yn),LCS(Xm,Yn1)}
可以看出 x m ≠ y n x_{m}\neq y_{n} xm=yn时,是通过动态规划解决的

递归实现

根据前面的推理,可以通过递归实现一个函数,用来计算LCS的长度:

def recursionlcs(X,Y):
    m=len(X)-1
    n=len(Y)-1
    #边界条件
    if m<0 or n<0:
       return 0
    elif X[m]==Y[n]:
       return recursionlcs(X[:m],Y[:n])+1
    else:
       return max(recursionlcs(X[:m],Y[:n+1]),recursionlcs(X[:m+1],Y[:n]))

fig1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值