前言

由于原微软开源的基于古老的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. js获取div基础元素

    1.js获取div元素 clientHeight 获取对象的高度,不计算任何边距.边框.滚动条,但包括该对象的补白. clientLeft 获取 offsetLeft 属性和客户区域的实际左边之间的距 ...

  2. wampserver apache 500 Internal Server Error解决办法

    Internal Server ErrorThe server encountered an internal error or misconfiguration and was unable to ...

  3. requests模拟浏览器请求模块初识

    requests模拟浏览器请求模块初识  一.下载 requests模拟浏览器请求模块属于第三方模块 源码下载地址http://docs.python-requests.org/zh_CN/lates ...

  4. 【django】另一种思路代替nginx 的rewrite

    需求:访问xx.com 跳转到xx.com/index 修改setting 同级别的urls.py 文件 from django.conf.urls import include, url from ...

  5. Python 去除字符串中的空行

    Python 去除字符串中的空行 mystr = 'adfa\n\n\ndsfsf' print("".join([s for s in mystr.splitlines(True ...

  6. Path variable [contentHash:8] not implemented in this context: styles.[contentHash:8].css

    webPack 升级到 4.3.0 导致 extract-text-webpack-plugin 无法使用  

  7. Educational Codeforces Round 50 (Rated for Div. 2) F - Relatively Prime Powers(数学+容斥)

    题目链接:http://codeforces.com/contest/1036/problem/F 题意: 题解:求在[2,n]中,x != a ^ b(b >= 2 即为gcd)的个数,那么实 ...

  8. 题解 [BZOJ4144] Petrol

    题目描述 ​ 有一张 n 个点 m 条边的无向图,其中有 s 个点上有加油站.有 Q 次询问(a,b,c), 问能否开一辆油箱容积为 c 的车从 a 走到 b.(a,b均为加油站) 输入格式 ​ 第一 ...

  9. HDU 6076 - Security Check | 2017 Multi-University Training Contest 4

    /* HDU 6076 - Security Check [ DP,二分 ] | 2017 Multi-University Training Contest 4 题意: 给出两个检票序列 A[N], ...

  10. SVN - Subversion

    Subversion yum install -y subversion 或者 subversion Edge 下载: # wget https://downloads-guests.open.col ...