zoukankan      html  css  js  c++  java
  • [字符串匹配收集]字符串匹配学习KMP

    1.KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程

    KMP算法,即Knuth-Morris-Pratt算法,是一种典型的基于前缀的搜索的字符串匹配算法。

    (1)next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。

    (2)next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符
    相同,且j的前面的1—k个字符与开头的1—k
    个字符不等(或者相等但T[k]==T[j])(1≤k<j)。
    如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]

    (3)next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个
    字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。
    即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]且T[j] != T[k].(1≤k<j);

    (4) next[j]=0 意义:除(1)(2)(3)的其他情况。

    2.算法实现

    #include <iostream>
    #include <string>
    using namespace std;
    
    void getNext(const char* pattern,int next[])
    {
    next[0]=-1;
    int k=-1,j=0;
    while(pattern[j]!='\0')
    {
    if(k!=-1 && pattern[k]!=pattern[j] )
    k=next[k];
    ++j;++k;
    if(pattern[k]==pattern[j])
    next[j]=next[k];
    else
    next[j]=k;
    }
    ////这里是我加的显示部分
    // for(int i=0;i<j;i++)
    //{
    // cout<<next[i];
    //}
    //cout<<endl;
    }
    
    void get_nextval(const char *T, int next[])
    {
    // 求模式串T的next函数值并存入数组 next。
    int j = 0, k = -1;
    next[0] = -1;
    while ( T[j/*+1*/] != '\0' )
    {
    if (k == -1 || T[j] == T[k])
    {
    ++j; ++k;
    if (T[j]!=T[k])
    next[j] = k;
    else
    next[j] = next[k];
    }// if
    else
    k = next[k];
    }// while
    ////这里是我加的显示部分
    for(int i=0;i<j;i++)
    {
    cout<<next[i];
    }
    cout<<endl;
    }// get_nextval 
    int KMP(const char *Text,const char *Pattern) //const 表示函数内部不会改变这个参数的值。
    {
    if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )//
    return -1;//空指针或空串,返回-1。
    int len=0;
    const char *c=Pattern;
    while(*c++!='\0')//移动指针比移动下标快。
    { 
    ++len;//字符串长度。
    }
    int *next=new int[len+1];
    get_nextval(Pattern,next);//求Pattern的next函数值
    
    int index=0,i=0,j=0;
    while(Text[i]!='\0' && Pattern[j]!='\0' )
    {
    if(Text[i]== Pattern[j])
    {
    ++i;// 继续比较后继字符
    ++j;
    }
    else
    {
    index += j-next[j];
    if(next[j]!=-1)
    j=next[j];// 模式串向右移动
    else
    {
    j=0;
    ++i;
    }
    }
    }//while
    
    delete []next;
    if(Pattern[j]=='\0')
    return index;// 匹配成功
    else
    return -1; 
    }
    int main()//abCabCad
    {
    char text[]="bababCabCadcaabcaababcbaaaabaaacababcaabc";
    char pattern[]="abCabCad";
    //getNext(pattern,n);
    //get_nextval(pattern,n);
    cout<<KMP(text,pattern)<<endl;
    return 0;
    }

    3.重点参考链接:

    http://blog.csdn.net/A_B_C_ABC/article/details/536925
    http://www.matrix67.com/blog/archives/115
    http://datasearch.ruc.edu.cn/~kaizhou/blog/
    http://blog.csdn.net/matrix67

    http://www.cnblogs.com/diewcs/archive/2010/10/03/1841781.html

    http://gmd20.blog.163.com/blog/static/16843923201161951547655/

    http://blog.csdn.net/aa2010aa/article/details/4999744

    http://www.longyusoft.com/detail.php?id=151

  • 相关阅读:
    java23种设计模式(五)--组合模式
    elasticsearch删除
    Jedis
    Redis主从复制(含哨兵模式)
    Redis持久化
    Redis基本知识(含数据类型)
    Linux学习(含有常用命令集)
    深入Kafka
    Kafka消费者
    Kafka生产者
  • 原文地址:https://www.cnblogs.com/moonflow/p/2468335.html
Copyright © 2011-2022 走看看