python最长公共连续子串_[Python]最长公共子序列 VS 最长公共子串[动态规划]

前言

由于原微软开源的基于古老的perl语言的Rouge依赖环境实在难以搭建,遂跟着Rouge论文的描述自行实现。

Rouge存在N、L、S、W、SU等几大子评估指标。在复现Rouge-L的函数时,便遇到了本博文的问题:求两串的最长公共子序列。

一 参考文献

全文参考均如下博文。

二 最长公共子序列 & 最长公共子串的区别

1、最长公共子序列(Longest Common Subsequence,LCS):在字符串A和字符串B中都出现的序列,且顺序与母串保持一致最长的那个序列。

2、最长公共子串(Longest Common Substring):相比LCS更加严格,序列必须连续出现,即公共的子字符串。

eg: csdnblog与belong,最长公共子序列为blog,最长公共子串为lo。

三 程序设计与实现

3.1 最长公共子序列

def longestCommonSubsequence(seqA, seqB):

"""

最长公共子序列

-----------

[reference] 最长公共子序列与最长公共子串【动态规划】 https://blog.csdn.net/a515557595_xzb/article/details/88296989

:param seqA:

:param seqB:

:return:

"""

m = len(seqA);

n = len(seqB);

init_unit={

"len":0,

"lcs":[]

}

dp = [[ init_unit ]*(n+1) for i in range(m+1)]; # m+1行, n+1列

for i in range(0, m+1):

for j in range(0, n+1):

if i==0 or j==0:

dp[i][j] = init_unit;

elif seqA[i-1] == seqB[j-1]:

tmp_str = copy.copy((dp[i-1][j-1])["lcs"]);

tmp_str.append(seqA[i-1]);

unit = {

"len": (dp[i-1][j-1])["len"] + 1,

"lcs": tmp_str

}

dp[i][j] = unit;

elif seqA[i-1] != seqB[j-1]:

if (dp[i-1][j])["len"] > (dp[i][j-1])["len"]: # 存储最长的信息

dp[i][j] = dp[i-1][j];

else:

dp[i][j] = dp[i][j-1];

else:

pass;

pass; # end inner for loop

pass; # end outer for loop

return dp[m][n];

print( longestCommonSubsequence("GM%$ABG", "gbndGFMABG") ) # {'len': 5, 'lcs': ['G', 'M', 'A', 'B', 'G']}

print( longestCommonSubsequence(["G", "M", "%", "$", "A", "B", "G"], ["g","b", "n", "d", "G", "F", "M", "A", "B","G"] ) ); # {'len': 5, 'lcs': ['G', 'M', 'A', 'B', 'G']}

3.2 最长公共子串

def longestCommonSubstring(strA, strB):

"""

最长公共子串

-----------

[reference] 最长公共子序列与最长公共子串【动态规划】 https://blog.csdn.net/a515557595_xzb/article/details/88296989

:param strA:

:param strB:

:return:

"""

m = len(strA);

n = len(strB);

init_unit={

"len":0,

"lcs":[]

}

dp = [[ init_unit ]*(n+1) for i in range(m+1)]; # m+1行, n+1列

result ={

"len":0, # 记录最长公共子串的长度

"lcs": []

};

for i in range(0, m+1): # 考虑i为0或j为0的情况

for j in range(0, n+1):

if i==0 or j==0 or ( strA[i-1] != strB[j-1] ):

dp[i][j] = init_unit;

elif strA[i-1] == strB[j-1]:

tmp_str = copy.copy((dp[i-1][j-1])["lcs"]);

tmp_str.append(strA[i-1]);

unit = {

"len": (dp[i-1][j-1])["len"] + 1,

"lcs": tmp_str

}

dp[i][j] = unit;

if (dp[i][j])["len"] > result["len"]: # 存储最长的信息

result = copy.copy( dp[i][j] );

else:

pass;

pass; # end inner for loop

pass; # end outer for loop

return result;

print( longestCommonSubstring("GM%$ABG", "gbndGFMABG") ) # {'len': 3, 'lcs': ['A', 'B', 'G']}

print( longestCommonSubstring(["G", "M", "%", "$", "A", "B", "G"], ["g","b", "n", "d", "G", "F", "M", "A", "B","G"] ) ); # {'len': 3, 'lcs': ['A', 'B', 'G']}

四 应用领域

4.1 机器学习 > 自动文本摘要 / 机器翻译 / 机器阅读理解等任务中 > 评估指标 > Rouge-L

Rouge-L分类:

句子级: 最长公共子序列

文摘级: Union[多条句子] 最长公共子序列

推荐论文: 《ROUGE: A Package for Automatic Evaluation of Summaries》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值