X-man

导航

hdu 1686 KMP算法

题意:

  求子串w在T中出现的次数。

kmp算法详解:http://www.cnblogs.com/XDJjy/p/3871045.html

 

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>

using namespace std;
int lenp;
int lens;
void getnext(int *next, char *p)
{
    int j = 0, k = -1;
    next[0] = -1;
    while(j < lenp)
    {

        if(k == -1 || p[j] == p[k])
        {
            j++;
            k++;
            next[j] = k;
        }
        else
            k = next[k];
    }
}

char s[1000100], p[10100];
int next[10100];
int main(void)
{
    int N;
    scanf("%d", &N);
    while( N-- )
    {

        scanf("%s", p);
        scanf("%s", s);
        lens=(int)strlen(s);
        lenp=(int)strlen(p);

        getnext(next, p);
        int i = 0;
        int j = 0;
        int sum = 0;

        while(i < lens&&j<lenp)
        {
            //printf("%d %d %c %c\n",i,j,s[i],p[j]);
            if( j == -1 || s[i] == p[j] )
            {

                i++;
                j++;
            }
            else
            {
                j = next[j];
            }
            //printf("#%d %d %c %c\n",i,j,s[i],p[j]);
            if( j >=lenp)
            {
                sum++;
                j = next[j];/////////!!!!!!!!!!
                //printf("%d %c %c\n",sum,s[i],p[j]);
            }
        }
        printf("%d\n", sum);
    }
    return 0;
}
View Code

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define L1 1000005
#define L2 10005

int next[L2], len1, len2, res;
char s[L1], p[L2];

void get_next ()
{
    int j = 0, k = -1;
    next[0] = -1;
    while (j < len2)
    {
        if (k == -1 || p[j] == p[k])
        {
            j++, k++;
            next[j] = k;
        }
        else k = next[k];
    }
}
void kmp (int pos)
{
    int i = pos, j = 0;
    while (i < len1 && j < len2)
    {
        //printf("%d %d %c %c\n",i,j,s[i],p[j]);
        if (j == -1 || s[i] == p[j])
        {
            i++, j++;
        }
        else j = next[j];
        //printf("#%d %d %c %c\n",i,j,s[i],p[j]);
        if (j >= len2)
                res++, j = next[j];    //神奇之处,效率大增
    }
}
int main()
{
    int t;
    scanf ("%d", &t);
    while (t--)
    {
        res = 0;
        scanf ("%s%s", p, s);
        len1 = strlen (s);
        len2 = strlen (p);
        get_next ();
        kmp (0);
        printf ("%d\n", res);
    }
    return 0;
}
View Code

 

posted on 2014-08-19 21:25  雨钝风轻  阅读(227)  评论(0编辑  收藏  举报