KMP算法解析

来源:互联网 发布:数据库查询手机号是 编辑:程序博客网 时间:2024/04/30 09:43

1.算法解决问题描述

       字符串匹配问题,即在长的字符串序列中去匹配短的字符串。

2.算法解析

       简单的字符串匹配是通过对匹配字符串平移一位,进行逐个比较。这样的话算法复杂度达到o(n*m).

KMP算法是首先得出匹配字符串的特征,这样当两个不匹配时,不用只是平移一位了。极大的减少

复杂度。它可以达到o(n+m)

KMP算法主要的是求覆盖函数(overlay_function)-——匹配字符串本身的特征

比如字符串:abaabcaba

子串a-1ab-1aba0abaa0abaab1abaabc-1abaabca0abaabcab1abaabcaba2

-1表示没有覆盖。

假如覆盖函数的值为k,则满足:a0a1...ak=aj-k...aj

可以采用递归的方法求覆盖函数。对pattern的前j+1序列字符,则有以下可能:

(1) patter[k+1]==pattern[j+1] 此时overlay(j+1)=k+1=overlay(j)+1;

(2)pattern[k+1]!=pattern[j+1] 此时只能在pattern的前k+1个子字符中找,h=overlay(k),如果pattern[h+1] == pattern[j+1]

    则overlay(j+1)=h+1;否则重复(2)过程。

<span style="font-size:14px;">void compute_overlay(const string& pattern){     const int pattern_length = pattern.size();     int *overlay_function = new int[pattern_length];     int index;     overlay_function[0] = -1;     for(int i=1;i<pattern_length;++i)      {           index = overlay_function[i-1];           while(index>=0 && pattern[i]!=pattern[index+1])           {               index = overlay_function[index];           }          if(pattern[i]==pattern[index+1])           {               overlay_function[i] = index + 1;           }           else            {                 overlay_function[i] = -1;             }          }         for(i=0;i<pattern_length;++i)        {            cout<<overlay_function[i]<<endl;         }       delete[] overlay_function;}</span>

KMP算法是:当发生在j长度不匹配时,只要把pattern向右移动 j-overlay(j) 长度就可以了。

<span style="font-size:14px;">int kmp_find(const string& target,const string& patter){  const int target_length = target.size();  const int pattern_length = pattern.size();  int * overlay_value = new int[pattern_length];  overlay_value[0] = -1;  int index = 0;  for(int i=1;i<pattern_length;++i)   {       index = overlay_value[i-1];       while(index>=0 && pattern[index+1]!=pattern[i])       {                index = overlay_value[index];        }        if(pattern[index+1]==pattern[i])        {           overlay_value[i] = index +1;        }        else        {             overlay_value[i] = -1;         }   }//match algorithm start    int pattern_index = 0;    int target_index = 0;    while(pattern_index<pattern_length&&target_index<target_length)   {        if(target[target_index]==pattern[pattern_index])       {            ++target_index;             ++pattern_index;        }       else if(pattern_index==0)       {           ++target_index;       }       else       {            pattern_index = overlay_value[pattern_index-1]+1;        }   }    if(pattern_index==pattern_length)    {          return target_index-pattern_index;     }     else     {          return -1;       }       delete [] overlay_value;}</span>




0 0
原创粉丝点击