什么叫做公共子序列?这里约定:一个字符串,按照从前到后,选择其中任意字符组成的新字符串,保证该字符串中的字符先后顺序与原来的字符串先后顺序不变,叫做子序列,公共,就是两个字符串有相同的子序列呗。
求两字符串的最长公共子序列!
怎么办?
简单的思想:一个字符串不动,另一个字符串的每一个字符分别进来比较,某两个字符相同,那就说明匹配上了,现在还有的问题没有解决,如果第二个字符串的第一个字符在第一个字符串接近末尾才出现,这个字符算不算公共子序列的一个字符?算的话,长度会大打折扣;不算的话,为什么不算,怎样才算?这是问题!!
动态规划怎么说的?算了,直接说方法吧,在这个过程中也许更好理解。
1、现在假设公共子序列已知,为Z,它是字符串X、Y的最大公共子序列,Z长度为L。
如果X和Y最后的一个字符相同,好办了,L等于XY两个字符串除了最后一个字符的前面的字符串的最长公共子序列长度加一,可以理解吧。如果Z最后一个字符与X最后一个字符不同,那就是说Z是X减去最后一个字符后和Y字符串最大的公共子序列,对吧。同理,如果Z最后一个字符与Y最后一个字符不同,那就是X字符串与Y减去最后一个字符剩下的字符串的最长子序列。
2、想到了1里面说的,那就递归好了,可能是X=Y=NULL,L=0;可能是L={X',Y'}+1 (注“{X',Y'}”意思是X去掉最后一个字符与Y去掉最后一个字符的最长子序列长度,排版问题,暂且这么理解吧);也可能是L=max{{X',Y},{X,Y'}};懂吧,不解释。
3、怎么写呢?二维数组,横Y竖X,相交处相同就在他左面或上面比较大的一个值加一(数组元素值代表比较到当前位置最大子序列长度),算了,上图上代码(伪代码)
m=X.length
n=Y,length
let b[1..m,1..n]and c[0..m,0..n]be new tables
for i=1 to m
c[i,0]=0
for j=0 to n
c[0,j]=0
for i=1 to m
for j=1 to n
if x[i]==y[i]
c[i,j]=c[i-1,j-1]+1
b[i,j]='¨I'
else if c[i-1,j]>=c[i,j-1]
c[i,j]=c[i-1,j]
b[i,j]='¡ü'
else
c[i,j]=c[i,j-1]
b[i,j]='¡û'
return c and b
代码和图参见算法导论原书第三版224页,我画的不好
4、按照图中浅蓝色部分输出子序列
我承认我写的不好,应该是我理解的还不够深吧!
明天继续学习,晚安!