KMP模板

来源:互联网 发布:淘宝客seo 编辑:程序博客网 时间:2024/06/03 16:53

首先计算next数组

  1. void GetNext(char* p,int next[])  

  2. {  

  3.     int pLen = strlen(p);  

  4.     next[0] = -1;  

  5.     int k = -1;  

  6.     int j = 0;  

  7.     while (j < pLen - 1)  

  8.     {  

  9.         //p[k]表示前缀,p[j]表示后缀  

  10.         if (k == -1 || p[j] == p[k])   

  11.         {  

  12.             ++k;  

  13.             ++j;  

  14.             next[j] = k;  

  15.         }  

  16.         else   

  17.         {  

  18.             k = next[k];  

  19.         }  

  20.     }  

  21. }  




然后就是进行匹配了

  1. int KmpSearch(char* s, char* p)  

  2. {  

  3.     int i = 0;  

  4.     int j = 0;  

  5.     int sLen = strlen(s);  

  6.     int pLen = strlen(p);  

  7.     while (i < sLen && j < pLen)  

  8.     {  

  9.         //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++      

  10.         if (j == -1 || s[i] == p[j])  

  11.         {  

  12.             i++;  

  13.             j++;  

  14.         }  

  15.         else  

  16.         {  

  17.             //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]      

  18.             //next[j]即为j所对应的next值        

  19.             j = next[j];  

  20.         }  

  21.     }  

  22.     if (j == pLen)  

  23.         return i - j;  

  24.     else  

  25.         return -1;  

  26. }  






顺带附上hdu2087的代码


剪花布条

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19850    Accepted Submission(s): 12406


Problem Description
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?
 

Input
输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
 

Output
输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
 

Sample Input
abcde a3aaaaaa aa#
 

Sample Output
03
 

这是一条模板题

代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<algorithm>
#include<algorithm>


using namespace std;
const int maxn=1005;




int nexta[maxn];
string s;//表示花纹布
string p;//表示小条子
void qiun()
{
    int plen=p.length();
    nexta[0]=-1;
    int k=-1;
    int j=0;
    while(j<plen-1)
    {
        if(k==-1||p[j]==p[k])
        {
            ++k;
            ++j;
            nexta[j]=k;
        }
        else
        {
            k=nexta[k];
        }
    }
}




int main()
{
    while(1)
    {
        cin>>s;
        if(s[0]=='#')
            return 0;
        cin>>p;


        int countn=0;
        int i=0;
        int j=0;
        int slen=s.length();
        int plen=p.length();
        qiun();
        while(i<slen)
        {
            //如果j=-1或者当掐字符匹配成功,都让i++,j++
            if(j==-1||s[i]==p[j])
            {
                i++;
                j++;


            }
            else
            {
                //如果j!=-1且当前字符匹配失败,则令i不变,j=next【j】
                j=nexta[j];
            }
            if(j==plen)
               {
                   countn++;
                   j=0;
               }
        }
        if(j==plen&&i-j)
            countn++;


        cout<<countn<<endl;


    }
    return 0;
}

0 0
原创粉丝点击