PART1. 题干
题目描述
牛可乐得到了两个字符串 sss 和 ttt ,牛可乐想请聪明的你帮他计算出来,两个字符串的最长公共子序列长度是多少。
最长公共子序列的定义是,子序列中的每个字符都能在两个原串中找到,而且每个字符的先后顺序和原串中的先后顺序一致。
输入描述:
输入包含多组数据,请读至文件末尾。
每行包含两个字符串 s,t,两个字符串用一个空格字符间隔,单个字符串长度不超过 5000。
数据保证所有数据的字符串 sss 长度之和与字符串 ttt 长度之和均不超过 5000。
输出描述:
对于每组数据,输出一个整数,代表最长公共子序列的长度。
示例1
abccde bcee
3
说明
最长公共子序列长度为 bcebcebce,长度为 3。
PART2. 题解
代码
import sys
for line in sys.stdin:
s,t = line.split()
lens=len(s)
lent=len(t)
rec=[[0 for x in range(lens+1)] for y in range(lent+1)]
for i in range(1,lent+1):
for j in range(1,lens+1):
if s[j-1]==t[i-1]:
rec[i][j]=rec[i-1][j-1]+1
else:
rec[i][j]=max(rec[i-1][j],rec[i][j-1])
print(rec[lent][lens])
解释:
首先,字符串遵从下标从0开始,到(字符串长度-1)结束,
所以其在字符串中的位置比在rec数组中少1。
rec[i][j]代表,截止字符串s中第i 个字符和字符串t 中第j 个字符,其最长的公共子序列。
rec二维数组中,rec[0][ ]和rec[ ][0]的部分用于充当‘‘哨兵’’的功能,全部设置为。
在状态转移的过程中,
如果字符串s中的第i个字符和字符串t中的第j个字符相同,那么很自然的,
最长的公共子序列的值就是在原先最长的子序列的长度上+1,
也就是:
rec[i][j]=rec[i-1][j-1]+1
如果字符串s中的第i个字符和字符串t中的第j个字符不相同,
代码中表现的是rec[i][j]=max(rec[i][j-1],rec[i][j-1])
如下图,
至于为什么是这么计算,每举一下所有情况,你会发现只有三种情况,均符合。至于为什么是这三种情况,仔细想想就会明白了😆😆😆😆。