LCS longest common sequence

### Python 实现一维数组的最长公共子序列 (LCS) 算法 最长公共子序列(Longest Common Subsequence, LCS)是一种经典的动态规划问题,用于寻找两个字符串或数组之间的最长公共部分。以下是基于动态规划方法的一个完整实现: #### 动态规划的核心思路 通过构建二维表 `dp` 来记录两个输入序列在不同位置上的匹配状态。对于长度分别为 `m` 和 `n` 的两个序列 `X` 和 `Y`,定义 `dp[i][j]` 表示 `X[:i]` 和 `Y[:j]` 的最长公共子序列长度。 如果当前字符相等,则有关系: \[ dp[i][j] = dp[i-1][j-1] + 1 \] 否则取前两种情况的最大值: \[ dp[i][j] = \max(dp[i-1][j], dp[i][j-1]) \] 最终结果存储于 `dp[m][n]` 中[^3]。 下面是完整的 Python 实现代码: ```python def lcs_length(X, Y): m = len(X) n = len(Y) # 创建一个(m+1)x(n+1)的矩阵来保存中间计算的结果 dp = [[0]*(n+1) for _ in range(m+1)] # 填充表格 for i in range(1, m+1): for j in range(1, n+1): if X[i-1] == Y[j-1]: dp[i][j] = dp[i-1][j-1] + 1 else: dp[i][j] = max(dp[i-1][j], dp[i][j-1]) # 返回最右下角的数值作为LCS长度 return dp[m][n] # 测试函数 if __name__ == "__main__": seq1 = "ABCBDAB" seq2 = "BDCAB" result = lcs_length(seq1, seq2) print(f"The length of the longest common subsequence is: {result}") ``` 上述代码实现了求解两串之间最长公共子序列的功能,并返回其长度。此算法的时间复杂度为 \(O(m \times n)\),其中 \(m\) 和 \(n\) 是输入序列的长度[^4]。 #### 进一步扩展功能——获取实际的 LCS 序列 除了得到 LCS 长度外,还可以回溯路径以获得具体的公共子序列内容。下面是一个改进版本,能够打印出对应的子序列: ```python def get_lcs_sequence(X, Y): m = len(X) n = len(Y) # 构建DP表 dp = [[0]*(n+1) for _ in range(m+1)] for i in range(1, m+1): for j in range(1, n+1): if X[i-1] == Y[j-1]: dp[i][j] = dp[i-1][j-1] + 1 else: dp[i][j] = max(dp[i-1][j], dp[i][j-1]) # 回溯找到具体序列 res = [] i, j = m, n while i > 0 and j > 0: if X[i-1] == Y[j-1]: res.append(X[i-1]) i -= 1 j -= 1 elif dp[i-1][j] >= dp[i][j-1]: i -= 1 else: j -= 1 return ''.join(res[::-1]) # 测试该增强版函数 seq1 = "ABCBDAB" seq2 = "BDCAB" lcs_seq = get_lcs_sequence(seq1, seq2) print(f"The Longest Common Subsequence is: {lcs_seq}") ``` 以上程序不仅给出了 LCS 的长度还提供了确切的内容表示形式[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值