码迷,mamicode.com
首页 > 其他好文 > 详细

kmp

时间:2019-03-16 23:41:58      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:res   names   字符   遍历   namespace   iostream   bsp   const   next数组   

 

/**
 *找str1中的一个子序列与str2相同 
 */
#include <iostream>
#include <vector> 
using namespace std;

class Search
{
    public:
        int s2_index_of_s1(const string &s1,const string &s2);
    private:
        vector<int> next;//遍历时依靠next数组加速 
        bool index(const string &str2);//求当前点的最长前缀==最长后缀的长度 
};
//前缀不包括最后一个字符,后缀不包括第一个字符 
bool Search::index(const string &str2)
{
    if(str2.length()<0)
        return false;
    
    next.resize(str2.length(),0);
    next.at(0)=-1;
    next.at(1)=0;
    int flag=0;
    for(int i=2;i<str2.length();)
    {
        if(str2.at(i-1)==str2.at(flag))
            next.at(i++)=++flag;
        else if(flag>0)
            flag=next.at(flag);
        else
            next.at(i++)=0;
    }
    return true;
}


int Search::s2_index_of_s1(const string &str1,const string &str2)
{
    if(!index(str2)||str2.length()>str1.length())
        return -1;
    int i=0,j=0;
    while(i<str1.length()&&j<str2.length())
    {
        if(str1.at(i)==str2.at(j))    
        {
            ++i;
            ++j;
        }
        else if(next.at(j)>0)//根据next数组来判断str下一个要移动的位置,可以直接移动最长后缀的长度 
            j=next.at(j);
        else
            ++i;
    }
    return j==str2.length()?i-j:-1;
}
int main()
{
    string str1("abcefd");
    string str2("abcdabccc");
    Search s;
    cout<<s.s2_index_of_s1(str1,str2)<<endl;
    return 0;
}

 

kmp

标签:res   names   字符   遍历   namespace   iostream   bsp   const   next数组   

原文地址:https://www.cnblogs.com/tianzeng/p/10544782.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!