前言

由于原微软开源的基于古老的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》

[Python]最长公共子序列 VS 最长公共子串[动态规划]的更多相关文章

  1. 用Python计算最长公共子序列和最长公共子串

    如何用Python计算最长公共子序列和最长公共子串 1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公 ...

  2. 动态规划1——最长递增子序列、最长公共子序列、最长公共子串(python实现)

    目录 1. 最长递增序列 2. 最长公共子序列 3. 最长公共子串 1. 最长递增序列 给定一个序列,找出其中最长的,严格递增的子序列的长度(不要求连续). 解法一:动态规划 通过一个辅助数组记录每一 ...

  3. [Data Structure] LCSs——最长公共子序列和最长公共子串

    1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...

  4. 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串

    LCS:给出两个序列S1和S2,求出的这两个序列的最大公共部分S3就是就是S1和S2的最长公共子序列了.公共部分 必须是以相同的顺序出现,但是不必要是连续的. 选出最长公共子序列.对于长度为n的序列, ...

  5. 最长公共子序列与最长公共字串 (dp)转载http://blog.csdn.net/u012102306/article/details/53184446

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  6. O(n log n)求最长上升子序列与最长不下降子序列

    考虑dp(i)表示新上升子序列第i位数值的最小值.由于dp数组是单调的,所以对于每一个数,我们可以二分出它在dp数组中的位置,然后更新就可以了,最终的答案就是dp数组中第一个出现正无穷的位置. 代码非 ...

  7. 【ZH奶酪】如何用Python计算最长公共子序列和最长公共子串

    1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...

  8. 最长公共子序列PK最长公共子串

    1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. (1)递归方法求最长公共子序列的长度 1) ...

  9. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

随机推荐

  1. 关于C++ Builder Codegurad 问题的排查。

    关于C++ BUILDER6 我目前不知道有什么特别好的内存排查工具.尤其为了对付memory leak, (Eurekalog 这个工具内存泄漏主要针对delphi,BCB配置比较繁琐). 除了BC ...

  2. C# 时间戳转换为时间格式

    // 时间戳转为格式 public DateTime StampToDateTime(string timeStamp) { DateTime dateTimeStart = TimeZone.Cur ...

  3. jwt、token

    什么是JWT jwt是一段密文;然而密码是如何产生的? 密码是由三个部分生成: 1.JWT头:JWT头部分是一个描述JWT元数据的JSON对象:{"alg":"hash2 ...

  4. Spring入门篇——第3章 Spring Bean装配(上)

    第3章 Spring Bean装配(上) 介绍Bean的作用域.生命周期.Aware接口.自动装配和Resource等内容. 3-1 Spring Bean装配之Bean的配置项及作用域 从上至下依次 ...

  5. mybayis项目使用的Mapping文件使用总结参考(二)

    针对in字句中的数组使用方法 <select id="getCpProfileNamesByIds" resultType="string"> se ...

  6. Java生成压缩文件(zip、rar 格式)

    jar坐标: <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</ar ...

  7. MyEclipse运行项目出现 The user operation is waiting for "Building workspace" to complete

    如图所示 解决方式 1.选择菜单栏的“Project”,然后把菜单栏中“Build Automatically”前面的对钩去掉. 2.当你修改或添加代码后,选择菜单栏的“Project”,然后选择菜单 ...

  8. CMake编译OpenCV

    使用CMake来编译OpenCV,以匹配自己使用的VS版本. 主要有两步: CMake编译OpenCV源码得到OpenCV.sln工程文件. VS编译OpenCV.sln. 以最新的cmake-3.1 ...

  9. 数据库中的using语句,以及与try……catch……finally的关系

    每new一个对象,就会开辟一块资源.using(我们new的对象){……},“}”处自动释放占用的资源(即调用Dispose方法).等效于fianlly中调用Dispose方法. Dispose内部会 ...

  10. Task , Thread 学习

    1.任务StartNew后就开始执行,使用Wait()来确保任务结束后继续 static void Main(string[] args) { try { int numberOfUsers = 10 ...