数据结构之 字符串---字符串匹配(kmp算法)

串结构练习——字符串匹配

Time Limit: 1000MS Memory limit: 65536K

题目描述

  给定两个字符串string1和string2,判断string2是否为string1的子串。
 

输入

 输入包含多组数据,每组测试数据包含两行,第一行代表string1,第二行代表string2,string1和string2中保证不出现空格。
 

输出

 对于每组输入数据,若string2是string1的子串,则输出"YES",否则输出"NO"。
 

示例输入

abc
a
123456
45
abc
ddd

示例输出

YES
YES
NO


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

using namespace std;

void GET_next(string t, int next[])
{
    int j, k;
    j=0; k=-1;
    next[0]=-1;
    int len=t.size();

    while(j<len )
    {
        if(k==-1 || t[j]==t[k] )
        {
            j++;
            k++;
            next[j]=k;
        }
        else
            k=next[k];
    }
}

int KMP(string s, string t, int next[] )
{
    int i, j;
    i=0; j=0;
    int len1=s.size();
    int len2=t.size();

    while(i<len1 && j<len2 )
    {
        if(j==-1 || s[i]==t[j] )
        {
            i++;
            j++;
        }
        else
            j=next[j];
    }
    if(j==len2 )
      cout<<"YES
";
    else
      cout<<"NO
";
    return 0;
}


int main()
{
    string s, t;
    int i, j;
    int len1, len2;
    int next[1000];

    while(cin>>s)
    {
        cin>>t;
        len1=s.size();
        len2=t.size();
        GET_next(t, next);
        KMP(s, t, next);
    }
    return 0;
}

 注释化:

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

using namespace std;

void GET_next(string t, int next[]) //生成next数组值
{
    int j, k;
    j=0; //字符串的位置下标的移动指针
    k=-1;
    next[0]=-1;//此处和课本不同,课本的下标从1开始,而实际是从0开始
    int len=t.size();

    while( j<len ) //t串长度
    {
        if(k==-1 || t[j]==t[k] )
        { //如果k=-1,往后移下标
            j++;
            k++;   //k代表:t1 t2 t3...tk = t(j-k+1) t(j-k+2)...t(j-1)
                   //的最大值
            next[j]=k; //next[当前] 被赋值
        }
        else
            k=next[k]; //k的回退
    }
    int i;
  /*for(i=0; i<len; i++)
    {
        cout<<next[i]<<" ";
    }
    cout<<endl; */

}
 /* 例如:t串:a b a a b c a c
         下标:0 1 2 3 4 5 6 7
       next:-1 0 0 1 1 2 0 1
 */
int KMP(string s, string t, int next[] )
{
    int i, j;
    i=0; j=0;
    int len1=s.size();
    int len2=t.size();
    //这是模式匹配过程
    while(i<len1 && j<len2 )// i指向母串 j指向子串
    {
        if(j==-1 || s[i]==t[j] )
        { //如果j=-1,(短路运算)直接向后移,因为没有-1的下标
          //如果下标合理,就比较二者指针对应的字符是否相等
            i++;
            j++;
        }
        else//如果上述两者条件不符
            j=next[j]; //让子串的指针j回退,而i不会移动,节省时间
    }
    if(j==len2 ) //如果跑玩匹配循环 j下标已经指向len2,则说明整个
                 //子串的字符都已被匹配上
      cout<<"YES
";
    else
      cout<<"NO
";
    return 0;
}

int main()
{
    string s, t;
    int i, j;
    int len1, len2;
    int next[1000];
    while(cin>>s) //读入母串
    {
        cin>>t;//读入子串
        len1=s.size(); //母串长度
       // len2=t.size(); //子串长度

        GET_next(s, next); //对子串t 生成next数组值
        //KMP(s, t, next);  //根据next数组进行kmp匹配
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yspworld/p/4098253.html