KMP 算法

来源:互联网 发布:ubuntu中vi命令的使用 编辑:程序博客网 时间:2024/05/01 04:21
#include <iostream>
#include 
<string>
#include 
<vector>
#include 
<algorithm>

using namespace std;

void get_next(const string& T,vector<int>& next )
{
    unsigned 
int i=0;
    next[
0= -1;
    
int k = -1;
    unsigned 
int j = 0;
    
while( j<T.size() -1 ) //每次总是计算下一值.
    {
        
if( k == -1 || T[j] == T[k])
        
{
            
++j;++k;
            next[j]
=k;
        }

        
else
            k
=next[k];
    }

    copy(next.begin(),next.end(),ostream_iterator
<int>(cout," "));
}


void get_nextval(const string& T,vector<int>& next )
{
    unsigned 
int i=0;
    next[
0= -1;
    
int k = -1;
    unsigned 
int j = 0;
    
while( j<T.size() -1 ) //每次总是计算下一值.
    {
        
if( k == -1 || T[j] == T[k])
        
{
            
++j;++k;
            
if(T[j] != T[k])     //if like this :aaaaaaab;
                next[j] = k;
            
else
                next[j] 
= next[k];
        }

        
else
            k
=next[k];
    }

    copy(next.begin(),next.end(),ostream_iterator
<int>(cout," "));
}

    
string T("abaabcac");
    vector
<int> next(T.size());
int Index_KMP( string s,string T,int pos)
{
    
int i=pos; 
    
int j=0;
    
while( i<s.size() && j<T.size())
    
{

        
if( (j==0 ||j==-1|| s[i]==T[j])
            
{++i;++j;}
        
else
            j
=next[j];
    }

    
if(j==T.size())
        
return i-j;
    
else
        
return 0;

}

int main()
{
    copy(T.begin(),T.end(),ostream_iterator
<char>(cout," "));
    cout
<<endl;
    get_next(T,next);

    
//string s("ababcabcacbab");
    string s("aaabaabaabcac");
    cout
<<endl;
    cout
<< Index_KMP(s,T,0);
    system(
"pause");
    
return 0;
}

KMP 是很经典,网上随便google一下就很多,我就不再对算法累述了.我所参考的是严未敏的<<数据结构>>第79页.

 KMP算法能在o(m+n)时间内完成串的匹配操作.(n 主窜长度,m子穿长度)想象一下,比如你编写了一个文本软件,再在上面实现查找功能.这时用kmp算法优势就体现出来了.

KMP包括两部分,匹配和求next值.匹配算法比较具体易懂,但求next函数代码技巧要求很高,如此简洁高效的实现不是凡人所为!     get_nextval是对get_next的改进,特别是当子窜是"aaaaab"之类(子窜中有多个连续相同字符)有更高的匹配效率.