模式匹配(KMP)

#include<stdio.h>
#include<string.h>
#define MAXN 50
int next[MAXN];///next做全局变量直接供自定义函数使用,就不需要传递参数了
int length(char *s)
{
    int i,len=0;
    for(i=0;s[i]!='\0';i++)
        len++;
    return len;
}
void getnext(char *s)///串字串,把字串的next的值求出来
{
    int j=-1;
    int i=0;
    next[0]=-1;///一开始字串的第一个位置肯定是没有共同的缀,初始化为-1
    int len=length(s);///求出子串的长度
    while(i<len)///变量子串
    {
        if(j==-1||s[i]==s[j])///j=-1,让它如果遇到不相同的进入的条件,
        {
            ++i;++j;///相同的话就同时进一位,j其实就是前缀和后缀的共同部分,共同部分的长度
            if(s[i]!=s[j])///这是优化版的next
                next[i]=j;///如果进入的条件是-1,而不是相等进入,那么就进入这里,也就告诉next没有共同部分,++j就是0
            else
                next[i]=next[j];///既然是相同的就继续找相同的共同缀
        }
        else
            j=next[j];///不相同的话,就从前缀后缀相同的部分接下来的位置继续走
    }
}


int kmp(char *s1,char *s2)///匹配
{
    int i=0,j=0;
    int s1_len=length(s1);///s1是主串,求出主串的长度
    int s2_len=length(s2);///s2是子串,求出子串的长度
    getnext(s2);///找子串的next的值
    while(i<s1_len&&j<s2_len)
    {
        if(j==-1||s1[i]==s2[j])///遇到相同的继续走
        {
            ++i;++j;
        }
        else
            j=next[j];///不同的时候从前面有前缀和后缀相等的部分的接下来的位置继续走
    }
    if(j==s2_len)///如果跑到了字串的长度,说明是匹配的
        return i-j;///返回i-子串的长度,也就是子串在主串的起始位置
    return -1;///否则返回-1,表示不匹配
}
int main()
{
    char s1[MAXN],s2[MAXN];
    int pos;
    printf("请输入主串:");
    scanf("%s",s1);
    printf("请输入要匹配的字串:");
    scanf("%s",s2);
    pos=kmp(s1,s2);
    if(pos==-1)
        puts("不匹配");
    else
        printf("字串在主串的  %d  的位置:\n",pos);


    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值