最长公共子串- LCS 算法
最长公共子串- LCS 算法
LCS (Longest Common Subsequence) 算法
已知字符串str1="网站高并发解决方案",str2="如何解决网站高并发",如何字符串最长公共子串?
lcs 算法原理
将2个字符串采用行列 排列:
|
如 |
何 |
解 |
决 |
网 |
站 |
高 |
并 |
发 | |
|---|---|---|---|---|---|---|---|---|---|
|
网 |
|||||||||
|
站 |
|||||||||
|
高 |
|||||||||
|
并 |
|||||||||
|
发 |
|||||||||
|
解 |
|||||||||
|
决 |
|||||||||
|
方 |
|||||||||
|
案 |
如果行列里面的字符相同,则表示1,否则为0:
|
如 |
何 |
解 |
决 |
网 |
站 |
高 |
并 |
发 | |
|---|---|---|---|---|---|---|---|---|---|
|
网 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
|
站 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
|
高 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
|
并 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
|
发 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
|
解 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
|
决 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
|
方 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
案 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
同时我们可以优化: 很明显,通过坐标可看到,相同的坐标已经标位1,通过计算连续对角线长度,即可比对出最长字符串.
如果行列里面的字符不相同,则表示为0,否则表示为 该坐标左上角的值后再加1:
|
如 |
何 |
解 |
决 |
网 |
站 |
高 |
并 |
发 | |
|---|---|---|---|---|---|---|---|---|---|
|
网 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
|
站 |
0 |
0 |
0 |
0 |
0 |
2 |
0 |
0 |
0 |
|
高 |
0 |
0 |
0 |
0 |
0 |
0 |
3 |
0 |
0 |
|
并 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
4 |
0 |
|
发 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
5 |
|
解 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
|
决 |
0 |
0 |
0 |
2 |
0 |
0 |
0 |
0 |
0 |
|
方 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
案 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
在判断字符串时,记录当前最大值与当前最大值坐标,判断完毕之后,即可通过记录的最大坐标获取到最长字符串最后的坐标值
public String LCS (String str1, String str2) {
// write code here
int m = str1.length();
int n = str2.length();
int[][] dp = new int[m][n];
int maxLength = 0;
int lastIndex = 0; //用来记录str1中最长公共串的最后一个字符的下标
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(str1.charAt(i) == str2.charAt(j)){ //判断str1中第i个字符是否和str2中第j个字符相等
if(i == 0 || j == 0){
dp[i][j] = 1;
}else{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
if(dp[i][j] > maxLength){ //判断是否需要更新最长公共子串
maxLength = dp[i][j];
lastIndex = i;
}
}
}
}
//通过str1来截取长度为maxLength, 最后字符坐标为lastIndex的子串
return str1.substring(lastIndex - maxLength + 1, lastIndex + 1);
}
我只是偶尔安静下来,对过去的种种思忖一番。那些曾经的旧时光里即便有过天真愚钝,也不值得谴责。毕竟,往后的日子,还很长。不断鼓励自己,
天一亮,又是崭新的起点,又是未知的征程(上校9)
逆水行舟,不进,则退!

浙公网安备 33010602011771号