解题思路:
char s[N];
* 声明一个字符数组 `s`,用于存储输入的字符串。
* **main 函数:**
* 进入一个循环,不断读取字符串 `s`,直到遇到字符串 `.` 为止。
* 对于每个输入的字符串 `s`,执行以下操作:
* 初始化 `ne` 数组的前两个元素为 0。
* 计算字符串 `s` 的长度 `len`。
* 重新计算 `ne` 数组,使用 KMP 算法。
* 如果字符串 `s` 的长度可以被最长重复子字符串的长度整除,则输出最长重复子字符串的长度。否则,输出 1。
**KMP 算法(重新计算 ne 数组):**
```cpp
// 重新求解 ne 数组
for (int i = 1, j = 0; i < len; i++)
{
while (j && s[i + 1] != s[j + 1]) j = ne[j];
if (s[i + 1] == s[j + 1]) j++;
ne[i + 1] = j;
}
```
* 使用两个指针 `i` 和 `j` 遍历字符串 `s`。
* 当 `s[i+1]` 与 `s[j+1]` 不相等时,`j` 指针回溯到 `ne[j]`。
* 当 `s[i+1]` 与 `s[j+1]` 相等时,`j` 指针前进一位。
* `ne[i+1]` 记录了 `s[0:i]` 与 `s` 的最长公共前缀的长度。
注意事项:
参考代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6 + 10;
char s[N];
int ne[N];
int main() {
while (cin >> s + 1 && s[1] != '.') {
// 计算字符串 s 的 next 数组
ne[0] = ne[1] = 0;
int len = strlen(s + 1);
// 重新求解 ne 数组
for (int i = 1, j = 0; i < len; i++)
{
while (j && s[i + 1] != s[j + 1]) j = ne[j];
if (s[i + 1] == s[j + 1]) j++;
ne[i + 1] = j;
}
// 判断
if (len % (len - ne[len]) == 0)
cout << len / (len - ne[len]) << endl;
else
cout << 1 << endl;
}
return 0;
}
0.0分
2 人评分