SDUT OJ 数据结构实验之串一:KMP简单应用 && 浅谈对看毛片算法的理解

数据结构实验之串一:KMP简单应用

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic Discuss

Problem Description

给定两个字符串string1和string2,判断string2是否为string1的子串。

Input

 输入包含多组数据,每组测试数据包含两行,第一行代表string1(长度小于1000000),第二行代表string2(长度小于1000000),string1和string2中保证不出现空格。

Output

 对于每组输入数据,若string2是string1的子串,则输出string2在string1中的位置,若不是,输出-1。

Sample Input

abc
a
123456
45
abc
ddd

Sample Output

1
4
-1

 

 

以此为例,浅谈对“看毛片”算法的理解;;

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char s1[1000005],s2[1000005];
int next[1000005];
void get_next(char *s)
{
    next[0] = -1;                 /*next[0]初始化为-1,-1表示不存在相同的最大前缀和最大后缀*/
    int k = -1;                   /*k初始化为-1*/
    int len = strlen(s);                
    for (int i=1; i<=len-1; i++)
    {
        while (k>-1 && s[k+1] != s[i])
                                  /*如果下一个不同,那么k就变成next[k],
                                           注意next[k]是小于k的,无论k取任何值。*/
            k = next[k];          /*往前回溯*/
        if (s[k+1] == s[i])       /*如果相同,k++*/
            k++;
        next[i] = k;              /*这个是把算的k的值
                                        (就是相同的最大前缀和最大后缀长)赋给next[i]*/
    }
}

int KMP( char *s, char *p )
{
    int len1 = strlen(s);
    int len2 = strlen(p);
    get_next( p );                      //计算next数组
    int k = -1;
    for (int i = 0; i < len1; i++)
    {
        while (k >-1&& p[k + 1] != s[i])//p和s不匹配,且k>-1(表示p和s有部分匹配)
            k = next[k];                //往前回溯
        if (p[k + 1] == s[i])
            k++;
        if (k == len2-1)                //说明k移动到p的最末端
                                        //cout << "在位置" << i-len2+1<< endl;
                                        //k = -1;//重新初始化,寻找下一个
                                        //i = i - len2 + 1;//i定位到该位置,外层for循环i++可以继续找下一个(这里默认存在两个匹配字符串可以部分重叠)。
            return i - len2 + 2;        //返回相应的位置
    }
    return -1;
}


int main()
{
    while( ~scanf("%s", s1) )
    {
        scanf("%s", s2);
        get_next( s2 );
        int wz = KMP( s1, s2 );
        printf("%d\n", wz );
    }
    return 0;
}

 

 

人如其名, 算法也是这样, 它真是对得起这个名字, 耐得把玩, 经的琢磨。

 

 两句话稍稍说下我的理解吧。

 

 KMP算法的应用于字符串匹配问题,就是比较原串的每一项跟子串的每一项,当遇到不匹配的一项时,原串标的位置不变,子串返回最长公共前后缀长度的下一位,再往后循环看是否匹配。next数组也叫失配数组,为了得到最长公共前后缀长度。

 

OK, 暂时就这些, 有空再详细理解理解吧。。

转载于:https://www.cnblogs.com/gaojinmanlookworld/p/10586914.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值