7-8 好后缀 (10分)
我们称一个字符串的后缀为好后缀,如果它满足如下条件:
(1)它在字符串中至少出现2次;
(2)满足条件(1)的最长者。
请编写程序计算一个字符串的好后缀长度,注意一个字符串不能称为自己的后缀。
输入输出描述
输入格式:
输入为一个字符串,包含不超过10^5个字母。
输出格式:
输出为一个整数,表示输入字符串的好后缀长度。
样例
输入样例1:
xacbacba
输出样例1:
4
输入样例2:
yxxabacaba
输出样例2:
3
输入样例3:
abc
输出样例3:
0
解题
首先看前缀函数定义:
根据定义知,next[i] = k;k就是以i为末尾下标的子串中,最长的相同真前后缀的长度,因此本题先将字符串逆转,然后就是求最大next[i]问题
代码
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 1e5 + 2;
char str[maxn];
int next_[maxn];
int ans;
void get_next(int next_[], char str[]) {
int len = strlen(str);
next_[0] = 0;
for (int i = 1; i < len; i++) {
/*j表示上一个匹配的长度, j - 1就是j长度的前缀的末尾下标*/
int j = next_[i - 1];
/*如果不匹配, j == 0 或 不匹配时退出循环*/
while (j > 0 && str[i] != str[j]) j = next_[j - 1]; //向前回溯查找
if (str[i] == str[j]) j++; //能够匹配
next_[i] = j;
ans = max(ans, j);
}
}
int main() {
scanf("%s", str);
reverse(str, str + strlen(str));
get_next(next_, str);
// for (int i = 0; i < strlen(str); i++) {
// printf("%d ", next_[i]);
// }
printf("%d\n", ans);
system("pause");
return 0;
}