题目描述
求两个字符串的最长公共子串长度。
输入格式
输入长度≤100的两个字符串S和T。
输出格式
输出两个字符串的最长公共子串长度。
输入样例
ABCBDAB
BDCABA
ABACDEF
PGHIK
输出样例
2
0
Code
/*
* @Description:
* @version:
* @Author:
* @Date: 2021-04-24 14:46:37
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-04-24 15:45:57
*/
// 与教材不同的是,本题要求子序列是连续的。
#include <iostream>
#include <string>
using namespace std;
// x[]存储X序列
// y[]存储Y序列
// L[][]存储最长公共子序列的长度
#define n 100
#define m 100
int L[m + 1][n + 1]; // L[i][j]表示x[0] - x[i] 和 y[0] - y[j]的最长子序列长度
int CommonOrder(string x, string y)
{
int i, j, k;
// 初始化第0行
for (j = 0; j <= x.length(); j++)
L[0][j] = 0;
// 初始化第0列
for (i = 0; i <= y.length(); i++)
L[i][0] = 0;
// 在两个序列开始出加一个无用字符,方便字符串下标为1-len(str)
x.insert(x.begin(), '1');
y.insert(y.begin(), '2');
// string maxstr;
int max = 0;
for (i = 1; i <= x.length(); i++)
for (j = 1; j <= y.length(); j++)
// 保证最近的两个字符是相等的,可以过滤掉一部分,否则,其实只有一个字符相等还按照这部分处理
if (x[i] == y[j] && x[i - 1] == y[j - 1])
{
// 两个位置字符相等,则这个位置的最长公共子序列长度就是L[i-1][j-1]+1
int temp = L[i - 1][j - 1] + 1;
bool flag = true;
// 当前保存了更大值
if (temp > max)
{
// 尝试把更大值给max
max = temp;
// 检查是否它最近max个字符相同,不是则恢复max,按照另外的情况处理
for (int k = 0; k < max; k++)
{
if (x[i - k] != y[j - k])
{
flag = false;
max--;
}
}
}
if (flag)
L[i][j] = temp;
else
{
if (L[i][j - 1] >= L[i - 1][j])
L[i][j] = L[i][j - 1];
else
L[i][j] = L[i - 1][j];
}
}
// 否则记录L[i][j-1]与L[i-1][j]中的较大者,记录决策
else if (L[i][j - 1] >= L[i - 1][j])
L[i][j] = L[i][j - 1];
else
L[i][j] = L[i - 1][j];
return L[x.length()][y.length()];
}
int main()
{
string x, y;
cin >> x >> y;
cout << CommonOrder(x, y) << endl;
system("pause");
return 0;
}