模式匹配KMP POJ 3461

来源:互联网 发布:sql分组累计求和 编辑:程序博客网 时间:2024/06/08 06:40

题目地址:http://poj.org/problem?id=3461


题目大意:在T串中找出W串出现的次数,T串的长度小于等于1000000,W串的长度小于等于10000。


解题思路:赤裸裸地KMP,可是最近果真总是作死的节奏,一直感觉我对地址下标、数字神马的比较敏感,今天卡了将近一个小时。。。


程序代码:

/*算法时间复杂度:O(m+n),m、n分别为两个串的长度。与传统算法的区别就是:每一趟匹配过程中出现字符比较不等时,                       不需回溯主串中用来指示字符的i指针                       而是利用已经得到的“部分匹配”的结果                       将模式串向右滑动尽可能远的距离,再进行比较。next[j]数组:表明当模式串中第j个字符与主串中第i个字符不匹配时,             在模式中需重新和该字符进行比较的字符的位置。*/#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>const int M = 1000010;char w[M];char t[M];int next[M];void Init(int w_len){    next[0] = -1;    int i = 0, j = -1;    while (i < w_len)    {        if (j == -1 || (w[i] == w[j]))        {            i++;            j++;            next[i] = j;        }        else j = next[j];    }}int Kmp(int w_len, int t_len){    int i = 0, j = 0;    int cnt = 0;    while (i < t_len)    {        if (j == -1 || (t[i] == w[j]))        {            i++;            j++;        }        else        {            j = next[j];        }        if (j >= w_len)        {            cnt++;        }    }    return cnt;}int main(){    int ncase;    scanf("%d", &ncase);    for (int i = 0; i < ncase; i++)    {        scanf("%s %s", w, t);        int w_len = strlen(w);        int t_len = strlen(t);        Init(w_len);        int ans = Kmp(w_len, t_len);        printf("%d\n", ans);    }    return 0;}

一点感悟:曾经要是好好静下心来学算法,不是盲目地刷题,该是多好~~    学习算法是件快乐的事情,加油!

0 0
原创粉丝点击