码迷,mamicode.com
首页 > 编程语言 > 详细

[2016-02-03][KMP算法]

时间:2016-02-04 01:07:08      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:

[2016-02-03][KMP算法]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const int maxn = 1E5 + 10;
const int maxm = 1E4 + 10;
int next[maxm];
int kkk[maxn];
void makenext(char P[]){
        //m p中的元素的数目
        //next[i] 表示 P和P自己匹配,第i个位置,对应的匹配的前缀字符串的末端的位置
        int m = strlen(P);
    memset(next, 0 , sizeof(int)*m);
    for(int i = 1,j = 0;i < m;){
        if(P[i] == P[j]) next[i++] = ++j;
        else if( j > 0) j = next[j - 1];
        else i++;
    }
}
int kmp(char T[],char P[])
{
    //T[] 需要进行匹配的数组
    //P[] 需要完全匹配的数组
    //n T中元素的数目
    //m P中元素的数目
        int n = strlen(T);
        int m = strlen(P);
    makenext(P);
    int i = 0,j = 0;//i表示当前匹配的位置
    for(;i < n;){//根据需要,可以对条件i < n进行更改,或者直接在循环内加上判断跳出
        if(T[i] == P[j]) kkk[i++] = ++j;//此时的j,表示P和T匹配,第i个位置,对应的匹配的前缀字符串的末端的位置
        else if( j > 0 ) j = next[j - 1];
        else i++;
        }
        //对生成的kkk数组的相关结果进行相关处理和判断
    return -1;
}

  • KMP算法的应用
    • strstr的优化
      • 1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        const int maxm = 1E4 + 10;
        int next[maxm];
        void makenext(char P[]){
                int m = strlen(P);
            memset(next, 0 , sizeof(int)*m);
            for(int i = 1,j = 0;i < m;){
                if(P[i] == P[j]) next[i++] = ++j;
                else if( j > 0) j = next[j - 1];
                else i++;
            }
        }
        int kmp(char T[],char P[]){
                int n = strlen(T);
                int m = strlen(P);
            makenext(P);
            for(int i = 0,j = 0;i < n;){
                if(T[i] == P[j]) i++,++j;
                else if( j > 0 ) j = next[j - 1];
                else i++;
         
                        if(j == m)      return i - m;
                }
            return -1;
        }
        int mystrstr(char str[],char strsearch[]){
                //在str中查找strsearch,
                //      如果找到,返回第一次出现的下标,
                //      否则返回-1
               return  kmp(str,strsearch);
        }
    • 循环节相关
      • 最后一位 未匹配部分长度如果能整除匹配部分长度,
      • 那么未匹配部分就是循环节(注意是否需要特殊处理,整个字符串是一个循环节的情况)
      • 1
        2
        3
        4
        5
        6
                int len = strlen(str);
                makenext(str);
                int tmp = len - next[len - 1];
                int res;
                if(len % tmp || tmp == len) res = tmp - len % tmp;//不是循环节,补成循环节需要的最少字符
                else res = 0;//是循环节
    • 回文字符串相关
      • 最后一个字符,未匹配部分补上去,整个字符串就是回文






[2016-02-03][KMP算法]

标签:

原文地址:http://www.cnblogs.com/qhy285571052/p/5180843.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!