试题传送门:831. KMP字符串
给定一个字符串 S,以及一个模式串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。
输入格式
第四行输入字符串 S。
输出格式
共一行,输出所有出现位置的起始下标(下标从 0 开始计数),整数之间用空格隔开。
数据范围
输入样例:
3 aba 5 ababa
输出样例:
0 2
P | a | b | c | a | b |
下标j | 1 | 2 | 3 | 4 | 5 |
ne[j] | 0 | 0 | 0 | 1 | 2 |
//j表示匹配成功的长度,i表示p数组中的下标
//因为p数组下标从1开始,ne[1]一定为0,所以i从2开始
for (int i = 2, j = 0; i <= n; i++) {
while (j && p[i] != p[j + 1]) j = ne[j]; //若不匹配,更新j到ne[j]
if (p[i] == p[j + 1]) j++; //成功即匹配下一个
ne[i] = j; //保存next数组
}
//j表示匹配成功的长度,从长度为0开始匹配
for (int i = 1, j = 0; i <= m; i++) {
while (j && s[i] != p[j + 1]) j = ne[j]; //若不匹配,更新j到ne[j]
if (s[i] == p[j + 1]) j++; //成功即匹配下一个
if (j == n) {
printf("%d ", i - j); //输出对应下标
j = ne[j]; //更新j,继续进行匹配
}
}
#include<iostream>
using namespace std;
constexpr int N = 100010, M = 1000010;
char p[N], s[M];
int ne[N];
int main() {
int n, m;
//字符串下标均从1开始
cin >> n >> p + 1 >> m >> s + 1;
//j表示匹配成功的长度,i表示p数组中的下标
//因为p数组下标从1开始,ne[1]一定为0,所以i从2开始
for (int i = 2, j = 0; i <= n; i++) {
while (j && p[i] != p[j + 1]) j = ne[j]; //若不匹配,更新j到ne[j]
if (p[i] == p[j + 1]) j++; //成功即匹配下一个
ne[i] = j; //保存next数组
}
//j表示匹配成功的长度,从长度为0开始匹配
for (int i = 1, j = 0; i <= m; i++) {
while (j && s[i] != p[j + 1]) j = ne[j]; //若不匹配,更新j到ne[j]
if (s[i] == p[j + 1]) j++; //成功即匹配下一个
if (j == n) {
printf("%d ", i - j); //输出对应下标
j = ne[j]; //更新j,继续进行匹配
}
}
return 0;
}
原文地址:https://blog.csdn.net/m0_73612497/article/details/134723652
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_34722.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!