ACM---字符串匹配(KMP算法)

KMP算法

1.寻找最长前缀后缀
如果给定的模式串是:“ABCDABD”,从左至右遍历整个模式串,求出最长前缀后缀
2.求next数组
next 数组考虑的是除当前字符外的最长相同前缀后缀,所以通过第①步骤求得各个前缀后缀的公共元素的最大长度后,只要稍作变形即可:将第①步骤中求得的值整体右移一位,然后初值赋为-1
3.进行匹配
根据最大长度表求出了next 数组后,从而有失配时,模式串向右移动的位数为:
失配字符所在位置 - 失配字符对应的next 值也就是j-next[j]。

#include<iostream>  
#include<cstring> 
#include<string>
using namespace std;  
int Next[10001];
//求KMP的Next数组  
void GetNext( string p)  
{  
    int i=0;  
    int j=-1;  
    Next[i]=j;  
    while(i<p.size())  
    {  
        if(j==-1||p[i]==p[j])  
        {  
            i++;  
            j++;  
            if(i==p.size()||p[i]!=p[j])
                Next[i]=j;  
            else  
                Next[i]=Next[j];  
        }  
        else  
        {  
            j=Next[j];  
        }  
    }  

} 


//S为母串,p为匹配子串,如果匹配返回匹配位置,否则返回-1  
int KMP(string s, string p)  
{  

    GetNext(p);//求得Next数组  
    int i=0;//在S串中的下标  
    int j=0;//在P串中的下标  
    int count=0;//匹配串出现的次数
    while(i<s.size())  
    {  
        if(j==-1||s[i]==p[j])  
        {  
            i++;  
            j++;  
        }  
        else  if(j<p.size())
            j=Next[j];  
        if(j==p.size())
        {
            count++;
            j=Next[p.size()];
        }
    }   
    return count;
}

int main()  
{  
    string str1;  
    string str2;  
    int n;
    cin>>n;
    while(n--)
    {
        cin>>str2;
        cin>>str1; 

        int pos=KMP(str1,str2);  
        cout<<pos<<endl; 

    }

    return 0;  
}  

猜你喜欢

转载自blog.csdn.net/oceansidexue/article/details/80315190
今日推荐