zoukankan      html  css  js  c++  java
  • kmp

    kmp是一种在线性时间内能处理两个字符串的包含关系的算法,例如求一个字符串里有没有另一个字符串,一个字符串里有几个另一个字符串(可重叠和不可重叠两种)。

    贴个讲kmp的链接http://blog.csdn.net/yutianzuijin/article/details/11954939

    模板

    #include<stdio.h>
    #include<string.h>
    void makeNext(const char P[],int next[])
    {
        int q,k;
        int m = strlen(P);
        next[0] = 0;
        for (q = 1,k = 0; q < m; ++q)
        {
            while(k > 0 && P[q] != P[k])
                k = next[k-1];
            if (P[q] == P[k])
            {
                k++;
            }
            next[q] = k;
        }
    }
    
    int kmp(const char T[],const char P[],int next[])
    {
        int n,m;
        int i,q;
        n = strlen(T);
        m = strlen(P);
        makeNext(P,next);
        for (i = 0,q = 0; i < n; ++i)
        {
            while(q > 0 && P[q] != T[i])
                q = next[q-1];
            if (P[q] == T[i])
            {
                q++;
            }
            if (q == m)
            {
                printf("Pattern occurs with shift:%d
    ",(i-m+1));
            }
        }    
    }
    
    int main()
    {
        int i;
        int next[20]={0};
        char T[] = "ababxbababcadfdsss";
        char P[] = "abcdabd";
        printf("%s
    ",T);
        printf("%s
    ",P );
        // makeNext(P,next);
        kmp(T,P,next);
        for (i = 0; i < strlen(P); ++i)
        {
            printf("%d ",next[i]);
        }
        printf("
    ");
    
        return 0;
    }
    View Code

    poj1961

    题目大意,求这个字符串到i为止有多少个循环串;

    int k = i-next[i];
    if((i+1)%k == 0 && (i+1)!= k)
    printf("%d %d ", i+1, (i+1)/k);

    这是代码的主要部分,求next数组的部分大家都知道,我来说说这部分的正确性;

    例如一个字符串的第99为指向第96位,也就是说后4-99位和前1-96位是匹配的,就是说94到96与97到99是是匹配的;

    而且91-94与94-96是匹配的。。。。。。。。。。。

    一直可以推到最前面,以上就是正确性啦~

    代码

    #include <iostream>
    #include <string.h>
    #include <map>
    #include <stdio.h>
    using namespace std;
    const int maxa =1000005;
    int next[maxa];
    int vis[maxa];
    int n;
    void init_kmp(char str[])
    {
    memset(vis, 0, sizeof(vis));
    next[0]=-1;
    for(int i=1;str[i]!=0;i++)
    {
    int j= next[i-1];
    while(str[j+1]!=str[i]&&j>=0)
    j= next[j];
    if(str[j+1] == str[i])
    next[i] = j + 1;
    else
    next[i] = -1;
    }
    }
    int main(){
    char str[maxa];
    int d =1;
    while(scanf("%d", &n), n){
    scanf("%s", str);
    printf("Test case #%d
    ", d++);
    init_kmp(str);
    for(int i = 0; i < n; i++){
    int k = i-next[i];
    if((i+1)%k == 0 && (i+1)!= k)
    printf("%d %d
    ", i+1, (i+1)/k);
    }
    printf("
    ");
    }
    }
    View Code
  • 相关阅读:
    IE6绿色版下载
    bcb 取相对路经
    MyEclipse 工具
    Flex与.NET互操作(一):基于Socket的网络连接
    兼容DC
    Flex与.NET互操作(二):基于WebService的数据访问(上)
    虚函数PostNcDestroy功能
    VC++多线程编程
    POJ 1222 extended lights out 高斯消元 板子题
    hihocoder 2015 北京区域赛 A Xiongnu's Land
  • 原文地址:https://www.cnblogs.com/icodefive/p/5176715.html
Copyright © 2011-2022 走看看