给出两个字符串 � 1 s 1 和 � 2 s 2 ,若 � 1 s 1 的区间 [ � , � ] [l,r] 子串与 � 2 s 2 完全相同,则称 � 2 s 2 在 � 1 s 1 中出现了,其出现位置为 � l。 现在请你求出 � 2 s 2 在 � 1 s 1 中所有出现的位置。 定义一个字符串 � s 的 border 为 � s 的一个非 � s 本身的子串 � t,满足 � t 既是 � s 的前缀,又是 � s 的后缀。 对于 � 2 s 2 ,你还需要求出对于其每个前缀 � ′ s ′ 的最长 border � ′ t ′ 的长度。 输入格式 第一行为一个字符串,即为 � 1 s 1 。 第二行为一个字符串,即为 � 2 s 2 。 输出格式 首先输出若干行,每行一个整数,按从小到大的顺序输出 � 2 s 2 在 � 1 s 1 中出现的位置。 最后一行输出 ∣ � 2 ∣ ∣s 2 ∣ 个整数,第 � i 个整数表示 � 2 s 2 的长度为 � i 的前缀的最长 border 长度。
时间: 2024-04-14 19:27:19 浏览: 85
根据题目描述,我们需要实现一个字符串匹配算法来找出字符串s2在字符串s1中出现的所有位置,并计算s2的每个前缀的最长border长度。下面是使用KMP算法实现的示例代码:
```cpp
#include <iostream>
#include <vector>
using namespace std;
vector<int> buildNext(const string& pattern) {
vector<int> next(pattern.size(), 0);
int i = 1, j = 0;
while (i < pattern.size()) {
if (pattern[i] == pattern[j]) {
j++;
next[i] = j;
i++;
} else {
if (j > 0) {
j = next[j-1];
} else {
next[i] = 0;
i++;
}
}
}
return next;
}
vector<int> kmp(const string& text, const string& pattern) {
vector<int> result;
vector<int> next = buildNext(pattern);
int i = 0, j = 0;
while (i < text.size()) {
if (text[i] == pattern[j]) {
i++;
j++;
if (j == pattern.size()) {
result.push_back(i - j);
j = next[j-1];
}
} else {
if (j > 0) {
j = next[j-1];
} else {
i++;
}
}
}
return result;
}
vector<int> computeBorderLengths(const string& pattern) {
vector<int> borderLengths(pattern.size(), 0);
int i = 1, j = 0;
while (i < pattern.size()) {
if (pattern[i] == pattern[j]) {
j++;
borderLengths[i] = j;
i++;
} else {
if (j > 0) {
j = borderLengths[j-1];
} else {
borderLengths[i] = 0;
i++;
}
}
}
return borderLengths;
}
int main() {
string s1, s2;
cin >> s1 >> s2;
vector<int> positions = kmp(s1, s2);
for (int i = 0; i < positions.size(); i++) {
cout << positions[i] << endl;
}
vector<int> borderLengths = computeBorderLengths(s2);
for (int i = 0; i < borderLengths.size(); i++) {
cout << borderLengths[i] << " ";
}
cout << endl;
return 0;
}
```
输入示例:
```
ABABDABACDABABCABAB
ABABCABAB
```
输出示例:
```
10
```
```
0 0 1 2 0 1 2 3 4
```
首先,我们使用`kmp`函数找出`s2`在`s1`中出现的所有位置,并将结果存储在`positions`向量中。然后,我们使用`computeBorderLengths`函数计算`s2`的每个前缀的最长border长度,并将结果存储在`borderLengths`向量中。最后,按照题目要求输出结果。
希望对你有所帮助!
阅读全文