LCS(longest common substring)算法,即最大公共子串,它是求两个字符串最长公共子串的问题。大体解法是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置. 例如,有两个字符串: A= I MISS MY CODE HI B= One Like MY Code 这里,先忽略掉大小写,通吃,在C#或者PHP中,String.ToLower()或者lower()可以考虑.对于其中的特殊字符,例如空格,可以在比较的时候直接删除.另外,该算法比较与顺序无关,可以随意的翻转字符串.接下来比较.
i | m | i | s | s | m | y | c | o | d | e | h | i | |
o | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
n | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
e | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
l | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
i | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
k | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
e | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
m | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
y | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
c | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
o | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
d | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
e | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
在上面的矩阵图中,其中的红色就可以看成匹配的字符串. 以下C#代码:
//Run By LCS.
public string GetSameString (string ArgA,string ArgB){
if(String.IsNullOrEmpty(ArgA) || String.IsNullOrEmpty(ArgB)) return String.Empty;
int[] CompareArr=new int[ArgB.Length];
int max=0,maxJ=0;
for(int iloop=0;iloop<ArgA.Length;iloop++){
for(int jloop=ArgB.Length-1;jloop>=0;jloop--){
CompareArr[jloop]=(ArgB[jloop]==ArgA[iloop])?( (iloop==0||jloop==0)?1:CompareArr[jloop-1]+1):0;
if(CompareArr[jloop]>=max){
max=CompareArr[jloop];
maxJ=jloop;
}
}
}
if(max>0){
return ArgB.Substring(maxJ-max+1,max);
}else return String.Empty;
}
注释:如果翻转后(可不翻转)相同,当前数组Index=N的值是N-1的值 + 1,这样,当最长的那条线上的就是最大的数字,同时,记录索引号.这样: Max 就是最多的匹配数, maxJ就是B字符串的索引. 亦可以这样理解: 竖的是A字符串,横的是B字符串,为了能在数组中记录上次的比较值,对单行进行倒循环,如果取值相同,该值是左上角的值加一,就是最长的字符串个数,即Max,同时记录当前的B字符串最后相同的索引值.然后用Substring()函数截取即可.