zoukankan      html  css  js  c++  java
  • KMP算法学习

    一、什么是KMP算法

    Knuth-Morris-Pratt 字符串查找算法(常简称为 “KMP算法”)是在一个“主文本字符串” S 内查找一个“词” W 的出现,,以此避免对以前匹配过的字符重新检查。(在原串中匹配模式串)


    二、KMP演示


    http://staff.ustc.edu.cn/~ypb/jpkc/flash/Find_KMP.swf


    三、KMP原理

    KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度。


    在KMP算法中有个数组,叫做前缀数组,也有的叫,每一个模式串都有一个固定的next数组,,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。


    对于next数组的理解,参见http://blog.csdn.net/yearn520/article/details/6729426#t0




    1. void SetPrefix(const char *Pattern, int prefix[])  
    2. {  
    3.      int i;  
    4.      int len=strlen(Pattern);//模式字符串长度。  
    5.      prefix[0]=0;  
    6.      for(i=1; i<len; i++)  
    7.      {  
    8.          int k=prefix[i-1];  
    9.          //不断递归判断是否存在子对称,k=0说明不再有子对称,Pattern[i] != Pattern[k]说明虽然对称,但是对称后面的值和当前的字符值不相等,所以继续递推  
    10.          while( Pattern[i] != Pattern[k] && k!=0 )//例i等于14时,求prefix[14]的值  
    11.              k=prefix[k-1]; //继续递归  
    12.          if( Pattern[i] == Pattern[k])//找到了这个子对称,或者是直接继承了前面的对称性,这两种都在前面的基础上++  
    13.               prefix[i]=k+1;  
    14.          else  
    15.               prefix[i]=0; //如果遍历了所有子对称都无效,说明这个新字符不具有对称性,清0  
    16.      }  
    17.   prefix[0]=-1;  
    18. }  

    四、测试小例
    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <string>  
    4. using namespace std;  
    5.   
    6. string sorg;  
    7. string spat;  
    8. int prefix[10000];  
    9. int result[20];  
    10.   
    11. void init()  
    12. {  
    13.     sorg="";  
    14.     spat="";  
    15.     memset(prefix,0,sizeof(int)*10000);  
    16.     //memset(result,0,sizeof(int)*20);  
    17. }  
    18. void setprefix(string temp,int next[])  
    19. {  
    20.     int len=temp.size();  
    21.     next[0]=0;  
    22.   
    23.     for(int i=1;i<len;i++)  
    24.     {  
    25.         int k=next[i-1];  
    26.   
    27.         while(temp[k]!=temp[i]&&k!=0)  
    28.             k=next[k-1];  
    29.   
    30.         if(temp[k]==temp[i])  
    31.             next[i]=k+1;  
    32.         else  
    33.             next[i]=0;  
    34.     }  
    35.   
    36.     next[0]=-1;  
    37.   
    38.     for(int i=0;i<len;i++)  
    39.         if(next[i]>=1)  
    40.             next[i]=next[i]-1;  
    41. }  
    42.   
    43. int  kmp(string s1,string s2)  
    44. {  
    45.     int number=0;  
    46.     int i=0;  
    47.     int j=0;  
    48.     while(i<(int)s1.size()&&j<(int)s2.size())  
    49.     {  
    50.         if(j==-1||s1[i]==s2[j])  
    51.         {  
    52.             i++;  
    53.             j++;  
    54.         }  
    55.         else  
    56.             j=prefix[j];  
    57.   
    58.         if(j==s2.size())  
    59.         {  
    60.             i=i-j+1;  
    61.             j=0;  
    62.             number++;  
    63.         }  
    64.     }  
    65.   
    66.     return number;  
    67. }  
    68. int main()  
    69. {  
    70.     int t;  
    71.     cin>>t;  
    72.     memset(result,0,sizeof(int)*20);  
    73.     for(int i=0;i<t;i++)  
    74.     {  
    75.         init();  
    76.         //cout<<"input spat string:"<<endl;  
    77.         cin>>spat;  
    78.   
    79.         //cout<<"input sorg string:"<<endl;  
    80.         cin>>sorg;  
    81.   
    82.         setprefix(spat,prefix);  
    83.         result[i]=kmp(sorg,spat);  
    84.     }  
    85.   
    86.     for(int j=0;j<t;j++)  
    87.         cout<<result[j]<<endl;  
    88.   
    89.   
    90.     return 0;  
    91. }  




  • 相关阅读:
    win10下vs2015配置Opencv3.1.0过程详解
    Int16, Int32, Int64 范围
    Microsoft Language and Locale Codes(微软语言和地区代码汇总)
    Azure china服务状态报告查看网址
    Azure IOT (EventHub + Stream Analytics + Table Storage)的使用
    java 继承extends 的相关知识点
    final
    java 垃圾回收机制
    Java 抽象类
    重载与重写、多态——java
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/3993836.html
Copyright © 2011-2022 走看看