KMP 算法

#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"之类(子窜中有多个连续相同字符)有更高的匹配效率.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值