我们说,“子序列”是由原字符串剔除了某些字符后所剩下字符按原来的顺序组成的。这“剩下字符”就是一段段连续的字符。我把每一段“剩下字符”称为“参与字串”[在图中用红色细框标出,下同],剔除的字串称为“不参与字串”[在图中用浅蓝色粗横线标出,下同]。
这行语句的作用就是:在下行的字符串(txt2,下同)中,剔除一个个“不参与字串”(其长度等于Tmp,下同)。取出一个个“参与字串”[Mid$(txt2, ......,下同],并且组成“最长公共子序列”[txt3 = txt3 & Mid$......]。
该语句在下面3种情况下使用:
情况1: 当上行字符串中有“不参与字串”时。(主过程里第一次出现的那一句)
情况2:当下行字符串里有“不参与字串”,而上行字符串中没有“不参与字串”时。(主过程里第二次出现的那一句))
情况3:在取出下行字符串里最后的“参与字串”时。[图例中:“,他的未婚妻”](主过程里最晚出现的那一句)
几个变量的说明:(在下行的字符串中)
n2 “不参与字串”之后一个字符的位置,也是后一个“参与字串”的第一个字的位置。(Ldot=n2)Ldot “参与字串”的第一个字的位置,它又是前一次这个语句中的n2。
Tmp “不参与字串”的长度。
Mid$(txt2, Ldot, n2 - Tmp - Ldot) 在下行字符串(txt2)中取出某一串“参与字串”的内容。
下面附上主过程和函数的VB代码:
Private Sub Command2_Click()
Dim i%, L1%, L2%, n1%, n2%
Dim txt1$, txt2$, txt3$
Dim Ldot%, Tmp%, gong2%, gong1%, Lian% '连,=6要连线,=7不连线
Dim zn1$, zn2$
Dim S1$, S2$, S3$, S4$, z1$
txt1 = Text1.Text
txt2 = Text2.Text
L1 = Len(txt1)
L2 = Len(txt2)
Text3.Text = ""
n1 = 1
n2 = 1
Ldot = 1
Do
If n1 <= L1 Then zn1 = Mid$(txt1, n1, 1) Else Exit Do
If n2 <= L2 Then zn2 = Mid$(txt2, n2, 1) Else Exit Do
If zn1 <> zn2 Then
gong1 = 0
gong2 = 0
Lian = 0
i = 0
Do
z1 = Mid$(txt1, n1 + i, 1)
If z1 = zn2 Then
Lian = 6
S2 = Mid$(txt1, n1 + i)
S3 = Mid$(txt2, n2)
S1 = Mid$(txt1, n1)
S4 = Mid$(txt2, n2 + 1)
gong2 = LCS(S1, S4)
gong1 = LCS(S2, S3)
If (gong2 > gong1) Then Lian = 7 '不连
If Lian = 6 Then'=6要连线
txt3 = txt3 & Mid$(txt2, Ldot, n2 - Tmp - Ldot)
Tmp = 0
Ldot = n2
n1 = n1 + i + 1
n2 = n2 + 1
Lian = 0
i = 0
Exit Do
End If
End If
i = i + 1
Lian = 7
Loop Until n1 + i > L1
If Lian = 7 Then
Tmp = Tmp + 1
n2 = n2 + 1
Lian = 0
End If
Else
If Tmp > 0 Then
txt3 = txt3 & Mid$(txt2, Ldot, n2 - Tmp - Ldot)
Ldot = n2
Tmp = 0
End If
n2 = n2 + 1
n1 = n1 + 1
End If
Loop Until ((n1 > L1) Or (n2 > L2))
txt3 = txt3 & Mid$(txt2, Ldot, n2 - Tmp - Ldot)
Tmp = 0
Text3.Text = txt3 & "---" & Len(txt3)
End Sub
Private Function LCS(B$, A$) As Integer
Dim L1%, L2%, n1%, n2%
Dim i%, m%, Lian% '连,=6要连线,=7不连线
Dim gong1%, gong2%
Dim zn1$, zn2$, b1$, a1$
Dim S1$, S2$, S3$, S4$, z1$
b1 = B
a1 = A
L1 = Len(b1)
L2 = Len(a1)
n1 = 1
n2 = 1
Do
If n1 <= L1 Then zn1 = Mid$(b1, n1, 1) Else Exit Do
If n2 <= L2 Then zn2 = Mid$(a1, n2, 1) Else Exit Do
If zn1 <> zn2 Then
gong1 = 0
gong2 = 0
Lian = 0
i = 0
Do
z1 = Mid$(b1, n1 + i, 1)
If z1 = zn2 Then
Lian = 6
S2 = Mid$(b1, n1 + i)
S3 = Mid$(a1, n2)
S1 = Mid$(b1, n1)
S4 = Mid$(a1, n2 + 1)
gong2 = LCS(S1, S4)
gong1 = LCS(S2, S3)
If gong2 > gong1 Then Lian = 7 '不连
End If
If Lian = 6 Then Exit Do
i = i + 1
Loop Until n1 + i > L1
If n1 + i > L1 Then Lian = 7
If Lian = 6 Then'=6要连线
m = m + 1
n1 = n1 + i + 1
n2 = n2 + 1
Lian = 0
i = 0
End If
If Lian = 7 Then
n2 = n2 + 1
Lian = 0
End If
Else
m = m + 1
n2 = n2 + 1
n1 = n1 + 1
End If
Loop Until ((n1 > L1) Or (n2 > L2))
LCS = m
End Function