KMP字符串匹配
本文最后更新于31 天前,其中的信息可能已经过时,如有错误请发送邮件到wsryhc@qq.com

原理:先对于要寻找的字符串进行搜索,然后在主字符串中继续搜索。

创建一个数组ne,记录每次返回的位置。
数组输入建议从1开始,0作为跳回点。
一开始,设定j为第一个元素前的位置,设定i为第二个元素的位置,然后对于第j+1位和第i位进行判断,
如果相同,那么j++,因为如果在第i位匹配不成功时,可以跳回之前重复的位置。(如果匹配第i位时不一样,那就可以跳回第j位重新开始)更新ne数组的第i个位置为j,也就是后面如果匹配到第i个位置发现不匹配,那就可以根据ne[i]进行跳回,也就是跳回j,然后继续判断;
如果不相同,那就先检查这个j是不是在第一个元素前的位置(也就是第0位),如果不在,那就证明之前一定有相同的结果(就是前面判断相同的地方),那就可以跳回去。假设为ababc,如果匹配到了第五位c不匹配,但是之前匹配ab时,第四位记录的跳回位置为1,也就是第二位的前一位,那就可以继续从ab开始匹配(也就是第三位开始寻找,如果后面有aba这样的就可以继续寻找)。
最后对于总的字符串进行匹配,还是从0开始,但是i=1,原理同上。只要发现j走到了要查找的字符串的末尾,那就代表查找成功,返回位置。

代码


#include<iostream>
using namespace std;
const int N = 100010, M = 1000010;
int n, m;
int ne[N];
char s[M], p[N];
int main()
{
cin >> n >> p + 1 >> m >> s + 1;
for (int i = 2, j = 0; i <= n; i ++ )
{
    while (j && p[i] != p[j + 1]) j = ne[j];    //开始先进行判断,如果不相等,就跳回上次的位置
    if (p[i] == p[j + 1]) j ++ ;    //如果相等,匹配的位置向后移动一位
    ne[i] = j;    //更新ne数组,第i个位置后如果不匹配可以跳回的位置
}
for (int i = 1, j = 0; i <= m; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == n)
    {
        printf("%d ", i - n);
        j = ne[j];
    }
}
return 0;
}
/*作者:yxc
链接:https://www.acwing.com/activity/content/code/content/43108/
来源:AcWing
*/
如果有不正确内容,欢迎发至wsryhc@qq.com反馈,谢谢!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇