两个字符串的最长相同子序列
描述:
求解两个字符串的最长子序列。输出其长度和子字符串
输入:
S1:abchifkdacb
S2:bcacbhiab
输出:
bchiab
解题思路:
可以利用求解出两个子字符串的最长长度,再求出其完成字符串的最长长度。
S1[0...i]与S2[0...j]的长度等于:{S1[0..i-1]与S2[0..j-1]加1}(此时S1[i]==S2[j])
{S1[0..i-1]与S2[0..j]和S1[0..i]与S2[0..j-1]中长度较大的那个}
求解子序列:
1 /// <summary> 2 /// 3 /// </summary> 4 /// <param name="firtLength"></param> 5 /// <param name="secondLength"></param> 6 /// <param name="S1">第一个字符串</param> 7 /// <param name="S2">第二个字符串</param> 8 /// <param name="M">计算长度数组</param> 9 /// <param name="N">是否相同数组</param> 10 public static void LCSLength(int firtLength, int secondLength, string S1, string S2, ref int[,] M, ref int[,] N) 11 { 12 if (firtLength == 0 || secondLength == 0) 13 return; 14 //从第一列开始向右逐个求解,求出最长子序列 15 for (int i = 1; i < firtLength; i++) 16 for (int j = 1; j < secondLength; j++) 17 { 18 if (S1[i] == S2[j]) 19 { 20 N[i, j] = 1; 21 M[i, j] = M[i - 1, j - 1] + 1; 22 } 23 else 24 { 25 if (M[i - 1, j] > M[i, j - 1]) 26 { 27 M[i, j] = M[i - 1, j]; 28 N[i, j] = 2; 29 } 30 else 31 { 32 M[i, j] = M[i, j - 1]; 33 N[i, j] = 3; 34 } 35 } 36 } 37 }
输出子序列:
1 /// <summary> 2 /// 输出其子字符串 3 /// </summary> 4 /// <param name="firstLength"></param> 5 /// <param name="secondLength"></param> 6 /// <param name="S1"></param> 7 /// <param name="N"></param> 8 public static void LCS(int firstLength, int secondLength, string S1, int[,] N) 9 { 10 if (firstLength == 0 || secondLength == 0) 11 return; 12 if (N[firstLength, secondLength] == 1) 13 { 14 LCS(firstLength - 1, secondLength - 1, S1, N); 15 Console.Write(S1[firstLength]); 16 } 17 else 18 { 19 if (N[firstLength, secondLength] == 2) 20 { 21 LCS(firstLength - 1, secondLength, S1, N); 22 } 23 if (N[firstLength, secondLength] == 3) 24 { 25 LCS(firstLength, secondLength - 1, S1, N); 26 } 27 } 28 }