说到求最长公共子串首先想到的是逐个子串比较,但是那样的话算法的复杂度太高,后来就想到用矩阵的方法去解决 思路如下:
比如字符创a:abcdefg 和字符串b:bdeabc 创建矩阵如下图所示
发现如果连续的斜线值为1的长度最长的话 则为最长公共子串 则abc为最长公共子串 ,
那我们可把矩阵进化为:
我们在计算矩阵的过程中判断如果它的值等于左上角的值+1
然后遍历矩阵找出最大值 则找到最长公共子串的结尾字符 往前移动该块的值 则为最长公共子串的起始地址;
代码如下:
void FindLString(string &s1, string s2)
{
int i = s1.length();
int j = s2.length();
int sum = 0;
int pos = 0;
//开辟二维数组
int **p = new int *[i];
for (int k = 0; k < i; k++)
{
p[k] = new int[j];
}
for (int ii = 0; ii < i; ii++)
{
for (int jj = 0; jj < j; jj++)
{
p[ii][jj] = 0;
if (s1[ii]==s2[jj])
{
if (ii>0 && jj>0)
{
p[ii][jj] = p[ii - 1][jj - 1] + 1;
if (p[ii][jj]>sum)
{
sum = p[ii][jj];
pos = jj;
}
}
else
{
p[ii][jj] = 1;
}
}
}
}
for (int k = 0; k < i; k++)
{
delete p[k] ;
}
for (int ii =pos-sum+1; ii <pos+1; ii++)
{
cout << s2[ii];
}
}
int _tmain(int argc, _TCHAR* argv[])
{
string a = "abcdefghaffheryeotwt";
string b = "bdeabcdffhertweituwet";
FindLString(a, b);
return 0;
}
ps:该代码只能求得一个最长公共子串 ,如果有多个 应该保存下来再输出