KMP,BF,STL之find函数,三种路径,分析如何进行模式串匹配

KMP,BF,STL之find函数,三种路径,分析如何进行模式串匹配

在这里插入图片描述

蒟蒻的我终于把KMP搞懂了,今天发一下博客记录一下,其实今天能搞懂这个KMP多亏了一个大佬的视频,我才能领悟KMP的精髓,为了帮助看到我博客的小伙伴能很好的理解,我要把这个大佬推荐给你们。下面就是视频:我的代码就是根据他的讲解思路写的。
`好!下面就是视频了,看不懂算我输。要认真看哦!这个系列视频有5个小片段,建议刚刚接触的同学,最好看完,有助于你理解KMP核心思想。`

KMP讲解

在这里插入图片描述

我写的代码是按照视频的思路来写的,我的next[i] 代表第前i+1个字母的公共最长前后缀。与很多博客,next[0]=-1不同,希望大家理解。关于next[0]=-1,接下来我会更新的,欢迎关注。个人觉得我写的那种比较好理解,而且不容易出错。

PS:这是最好理解的一种

KMP算法模式串匹配(模式串下标从0开始):
#include<stdio.h>
#include<string.h>
int main()
{
    char s1[110];
    char s2[110];
    printf("请输入两行字符串,分别表示主串和模式串:\n");
    while(~scanf("%s%s",s1,s2))
    {
        int next[110];
        next[0]=-1;        //由于书上的字符串是以1开头所以next[0]=0,而我是以0开头,所以next[0]=-1,至于为啥,我觉得自己手动算下应该就明白了
        int i=0;
        int j=-1;            //重点!!!!!
        int len1=strlen(s1);
        int len2=strlen(s2);
        while(i<len2)
        {
            if(j==-1||s2[i]==s2[j])     //由于next[0]=-1,所以对j==-1特判下
            {
                ++i;
                ++j;
                next[i]=j;
            }
            else
            {
                j=next[j];
            }
        }
        i=0;
        j=0;
        while(i<len1&&j<len2)
        {
            if(s1[i]==s2[j]||j==-1)    //同样由于next[0]=-1的存在
            {
                ++i;
                ++j;
            }
            else
            {
                j=next[j];   //这里就不需要指针回溯,大大降低了时间复杂度
            }
        }
        if(j==len2)
        {
            printf("%d\n",i-len2+1);
        }
        else
            printf("0\n");
    }
    return 0;
}



KMP算法模式串匹配:
//  KMP算法模式串匹配
#include <bits/stdc++.h>
using namespace std;
int main()
{
    char a[105];
    char b[1005];
    memset(a, '\0', sizeof(a));
    memset(b, '\0', sizeof(b));
    while (~scanf("%s%s", a, b))
    {
        int next[105] = {0};
        scanf("%s%s", a, b);
        int i = 1, j = 0;
        while (i < strlen(a))
        {
            if (a[i] == a[j])
                next[i++] = ++j;
            else
            {
                if (j > 0)
                    j = next[j - 1];
                else
                    i++;
            }
        }
        for (int i = 0; i < strlen(a); ++i)
            printf("%d ", next[i]);
        printf("\n");
        i = 0;
        j = 0;
        while (i < strlen(b))
        {
            if (a[j] == b[i])
            {
                ++i;
                ++j;
                if (j == strlen(a))
                {
                    printf("%d\n", i - j);
                    j = next[j - 1];
                }
            }
            else
            {
                if (j > 0)
                    j = next[j - 1];
                else
                    ++i;
            }
        }
        memset(a, '\0', sizeof(a));
        memset(b, '\0', sizeof(b));
    }
    return 0;
}
KMP算法模式串匹配(模式串下标从1开始):
#include <bits/stdc++.h>
using namespace std;
const int cmax = 1e3 + 5;
char str[cmax];
int nex[cmax];
char t[cmax];
void get_next(char T[])
{
    int i = 1, j = 0, len = strlen(T) - 1;
    nex[1] = 0;
    while (i < len)
    {
        if (j == 0 || T[i] == T[j])
        {
            ++i;
            ++j;
            nex[i] = j;
        }
        else
            j = nex[j];
    }
}
int Index_KMP(char s[], char t[], int pos)
{
    int i = pos, j = 1, slen = strlen(s) - 1, tlen = strlen(t) - 1;
    while (i <= slen && j <= tlen)
    {
        if (j == 0 || s[i] == t[j])
        {
            i++, j++;
        }
        else
            j = nex[j];
    }
    if (j > tlen)
        return i - tlen;
    else
        return 0;
}
int main()
{
    memset(str, '\0', sizeof(str));
    memset(nex, 0, sizeof(nex));
    memset(t, '\0', sizeof(t));
    scanf("%s%s", t, str);
    for (int i = strlen(str) - 1; i >= 0; i--)
        str[i + 1] = str[i];
    for (int i = strlen(t) - 1; i >= 0; i--)
        t[i + 1] = t[i];
    get_next(str);
    int flag = Index_KMP(t, str, 1);
    printf("%d\n", flag);
    memset(nex, 0, sizeof(nex));
    return 0;
}

BF算法模式串匹配:
//   BF算法模式串匹配
#include <bits/stdc++.h>
using namespace std;
int main()
{
    char a[105];
    char b[1005];
    memset(a, '\0', sizeof(a));
    memset(b, '\0', sizeof(b));
    while (~scanf("%s%s", a, b))
    {
        int alen = strlen(a), blen = strlen(b);
        int i = 0, j = 0;
        while (i < blen)
        {
            if (a[j] == b[i])
            {
                ++j;
                ++i;
                if (j == alen)
                {
                    printf("%d\n", i - j);
                    j = 0;
                    i = i - j + 1;
                }
            }
            else
            {
                j = 0;
                i = i - j + 1;
            }
        }
        memset(a, '\0', sizeof(a));
        memset(b, '\0', sizeof(b));
    }
    return 0;
}
STL中String的find函数应用:
//   STL中String的find函数应用
#include <bits/stdc++.h>
using namespace std;
int main()
{
    string a, b;
    while (cin >> a >> b)
    {
        int flag = b.find(a);
        if (flag == -1)
            printf("NO FOUND\n");
        else
        {
            while (flag != b.npos)
            {
                printf("%d\n", flag);
                flag++;
                flag = b.find(a, flag);
            }
        }
    }
    return 0;
}

当然,STL肯定比KMP好用。推荐对acm感兴趣的同学可以了解一下STL

对于STL的string不是很懂的同学可以看一下下面的博客:

STL之string函数详解

对于STL感兴趣的同学,可以关注一下这个博主,没错,就是不要脸的我,就是我的博客,我对自己写的东西还是有一丢丢的自信的,对了,我也是一名acm狗,但是我蒟蒻,我愿意和关注我的小伙伴一起进步。

一位蒟蒻的acm狗的博客

Yqifei的博客

在这里插入图片描述

在这里插入图片描述

如果不想关注,就点个赞吧!毕竟写博客不易,你的支持就是最好的鼓励

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liknana

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值