[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评价方法详解(二)
- 推荐论文: 《ROUGE: A Package for Automatic Evaluation of Summaries》
- Rouge-L分类:
[Python]最长公共子序列 VS 最长公共子串[动态规划]的更多相关文章
- 用Python计算最长公共子序列和最长公共子串
如何用Python计算最长公共子序列和最长公共子串 1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公 ...
- 动态规划1——最长递增子序列、最长公共子序列、最长公共子串(python实现)
目录 1. 最长递增序列 2. 最长公共子序列 3. 最长公共子串 1. 最长递增序列 给定一个序列,找出其中最长的,严格递增的子序列的长度(不要求连续). 解法一:动态规划 通过一个辅助数组记录每一 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串
LCS:给出两个序列S1和S2,求出的这两个序列的最大公共部分S3就是就是S1和S2的最长公共子序列了.公共部分 必须是以相同的顺序出现,但是不必要是连续的. 选出最长公共子序列.对于长度为n的序列, ...
- 最长公共子序列与最长公共字串 (dp)转载http://blog.csdn.net/u012102306/article/details/53184446
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- O(n log n)求最长上升子序列与最长不下降子序列
考虑dp(i)表示新上升子序列第i位数值的最小值.由于dp数组是单调的,所以对于每一个数,我们可以二分出它在dp数组中的位置,然后更新就可以了,最终的答案就是dp数组中第一个出现正无穷的位置. 代码非 ...
- 【ZH奶酪】如何用Python计算最长公共子序列和最长公共子串
1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...
- 最长公共子序列PK最长公共子串
1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. (1)递归方法求最长公共子序列的长度 1) ...
- 动态规划(一)——最长公共子序列和最长公共子串
注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...
随机推荐
- Linux的基础使用命令
ifconfig #查看ip地址 或者使用 ip a pwd #查看当前工作路径 man pwd #查看命令的详细信息 按q退出 mkdir /data 创建data目录 ...
- linux批量添加用户和批量修改密码
一.批量创建用户通过命令newusers可以实现批量的创建用户.这个命令的用法为 newusers file.txt(一个文本文件)文本文件内存放需要批量添加的用户信息但是对格式有要求格式:pw_na ...
- 01—mybatis开山篇
什么是 MyBatis ? MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.M ...
- PLSQL打开文件中文出现乱码
假定数据库使用的是:American_America.AL32UTF8字符集. 查询方式:SELECT * FROM v$nls_parameters ; 查看NLS_CHARACTERSET 的值是 ...
- SpringBoot 配置 Tomcat SSL
SpringBoot 配置 Tomcat SSL SSL(Secure Sockets Layer , 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密 ...
- 调用WebService接口返回字符串
Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddr ...
- Python3-def
def hello(): print("这是一个无参数的方法!") hello(); print("") def helloOne(str): print(st ...
- spring注解@Import和@ImportResource
@Import只负责引入javaCOnfig形式定义的Ioc容器配置,等同于<import resource="xxx.xml"/>将一个配置文件导入另一个 @Conf ...
- HDU 6048 - Puzzle | 2017 Multi-University Training Contest 2
/* HDU 6048 - Puzzle [ 思维,结论 ] | 2017 Multi-University Training Contest 2 题意: 类似华容道的问题, N*M 的矩阵中N*M- ...
- Codeforces Round #452 (Div. 2) 899E E. Segments Removal
题 OvO http://codeforces.com/contest/899/problem/E Codeforces Round #452 (Div. 2) - e 899E 解 用两个并查集(记 ...