华电北风吹
日期:2016/2/22
题目描述:
找两个字符串的最长公共子串是一个很简单的问题,注意这里的子串必须连续。
解题思路:
例如对于字符串abcb和字符串cbc可以构建如下二维矩阵,匹配为1不匹配为0即可。这样直接看主对角线上连续1的最大长度即可。
c b c
a 0 0 0
b 0 1 0
c 1 0 1
b 0 1 0
对于主对角线上连续1的个数可以使用动态规划求解。在这里不妨直接把动态规划的思路添加到二维矩阵的构建里面。在构建的时候如果发现匹配了,就对这个元素赋值为它左上角的元素加1即可(具体见下面表格)。这样存储过程中由于只用相邻两行,所以用两行矩阵就够了。需要注意的是需要时刻对最大值进行判别保存。
c b c
a 0 0 0
b 0 1 0
c 1 0 2
b 0 2 0
参考代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Solution
{
public:
string LCS(const string& str1, const string& str2)
{
int len1 = str1.size();
int len2 = str2.size();
vector<int> state1(len2 + 1);
vector<int> state2(len2 + 1);
vector<int> *pStateNew = NULL, *pStateLast = NULL;
bool flag = false;
int pos = 0, maxlen = 0;
for (int i = 0; i<len1; i++)
{
if (flag == false)
{
pStateLast = &state1;
pStateNew = &state2;
}
else
{
pStateLast = &state2;
pStateNew = &state1;
}
for (int j = 1; j <= len2; j++)
{
if (str1[i] == str2[j - 1])
(*pStateNew)[j] = (*pStateLast)[j - 1] + 1;
else
(*pStateNew)[j] = 0;
if ((*pStateNew)[j] > maxlen)
{
pos = j;
maxlen = (*pStateNew)[j];
}
}
flag = !flag;
}
string res = str2.substr(pos - maxlen, maxlen);
return res;
}
};
int main()
{
string str1("abcb");
string str2("cbc");
Solution s;
string lcs = s.LCS(str1, str2);
cout << lcs << endl;
return 0;
}