SDUT KMP简单应用

Posted on 2014-02-11 14:44  ttop  阅读(149)  评论(0编辑  收藏  举报

KMP简单应用

Time Limit: 1000MS Memory limit: 65536K

题目描述

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

输入

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

输出

 对于每组输入数据,若string2是string1的子串,则输出string2在string1中的位置,若不是,输出-1。

示例输入

abc
a
123456
45
abc
ddd

示例输出

1
4
-1

提示

 

来源

cjx

示例程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char A[1000000],a[1000000] ;
int next[1000000];

void get_next( int *next,char *a,int la) /*求NEXT[]的值*/
{
     int i=1,j=0 ;
     next[1] = 0 ;

     while ( i <= la) /*核心部分*/
     {
           if( a[i] == a[j] || j == 0 )
           {
               j ++ ;
               i ++ ;
               if( a[i] == a[j])
               next[i] = next[j];
               else
               next[i] = j ;
           }
           else
           j = next[j] ;
     }
}


int  str_kmp( int *next, char *A ,char *a, int lA,int la)/* EASY*/
{
     int i,j,k ;
     i = 1 ;
     j = 1 ;
     while ( i<=lA && j <= la )
     {
           if(A[i] == a[j] ||  j == 0 )
           {
                   i ++ ;
                   j ++ ;
           }
           else
           j = next[j] ;
     }

     if ( j> la)
     return i-j+1 ;
     else
     return -1 ;
}

int main(void)
{
    int n,k;

    int lA=0,la =0 ;
    while(scanf("%s %s",&A,&a)!=EOF)
    {
    lA = strlen(A);
    la = strlen(a);
    for(k=la-1; k>= 0 ;k --)
    a[k+1] = a[k] ;
    for(k=lA-1; k>= 0 ;k --)
    A[k+1] = A[k] ;

    get_next(next,a,la) ;
    k = str_kmp(next,A,a,lA,la);
    if ( -1 == k)
    printf("-1\n");
    else
    printf("%d\n",k) ;
    }
    return 0;
}