题目描述:
求采用顺序结构存储的串s和串t的一个最长公共子串,若没有则输出false,若最长的有多个则输出最先出现的那一串。
输入:
输入两个字符串
输出:
输出公共子串
样例输入:
abcdef
adbcef
样例输出:
bc
实现代码1:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
#include <string>
using namespace std;
typedef long long LL;
const int maxn = 1010;
const LL p = 1e7 + 19;
const LL mod = 1e9 + 7;
LL powP[maxn], H1[maxn] = {0}, H2[maxn] = {0};
struct Node {
int hashValue, length, start, end;
Node(int a, int b, int c, int d): hashValue(a), length(b), start(c), end(d) {};
};
vector<Node> pr1, pr2;
void init(int len) {
powP[0] = 1;
for(int i = 1; i <= len; ++i) {
powP[i] = (powP[i - 1] * p) % mod;
}
}
void calH(LL H[], string &str) {
H[0] = str[0];
for(int i = 1; i < str.length(); ++i) {
H[i] = (H[i - 1] * p + str[i]) % mod;
}
}
int calSingleSubH(LL H[], int i, int j) {
if(i == 0)
return H[j];
return ((H[j] - H[i - 1] * powP[j - i + 1]) % mod + mod) % mod;
}
void calSubH(LL H[], int len, vector<Node> &p) {
for(int i = 0; i < len; ++i)
for(int j = i; j < len; ++j) {
int value = calSingleSubH(H, i, j);
p.push_back(Node(value, j - i + 1, i, j));
}
}
string getMax(string str1) {
string str;
int ans = 0;
for(int i = 0; i < pr1.size(); ++i)
for(int j = 0; j < pr2.size(); ++j) {
if(pr1[i].hashValue == pr2[j].hashValue) {
if(pr1[i].length > ans) {
ans = pr1[i].length;
str = str1.substr(pr1[i].start, pr1[i].length);
}
}
}
return str;
}
int main() {
string str1, str2;
while(cin>>str1>>str2){
init(max(str1.length(), str2.length()));
calH(H1, str1);
calH(H2, str2);
calSubH(H1, str1.length(), pr1);
calSubH(H2, str2.length(), pr2);
cout << getMax(str1) << endl;
}
return 0
}
实现代码2:
#include<iostream>
#include<string>
using namespace std;
int main() {
string a, b;
while (cin >> a >> b) {
int num = 0, index, dp[110][110] = { 0 };//dp:串a前i位和串b前j位最大子串长度
a = " " + a, b = " " + b;//下标从1方便
for (int i = 1; i < a.length(); i++) {
for (int j = 1; j < b.length(); j++) {
if (a[i] == b[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
if (dp[i][j] > num) {
num = dp[i][j];
index = i - dp[i][j] + 1;
}
}
}
cout << a.substr(index, num) << endl;
}
return 0;
}
/*
动态规划求解,跟最长公共子序列差不多
*/