KMP算法_读书笔记

下面是KMP算法的实现伪代码:

KMP_MATCHER ( T, P )
1.  n = T.length 
2.  m = P.length
3.  next = COMPUTE_PREFIX_FUNCTION ( P )
4. q = 0         //number of characters matched
5. for i = 1 to n      //scan the text from left to right
6.      while q > 0 and P [q+1] <> T[i]
       //next character does not match
7.       q = next[q]
8.       if P[q+1 ] == T [i]  // next character matches
9.      q = q+1         
10.     if  q == m        // is all the characters in P matched
11.    finish
12.     q = next[q]        // look for the next matcher



COMPUTE_PREFIX_FUNCTION ( P ) 1 m = P.length 2 let next be a new array with length of m 3 next[1] = 0 4 k = 0 5 for q = 2 to m 6 while k>0 and P[k+1] <> P[q] 7 k = next [k] 8 if P[k+1] == P[q] 9 k = k+1 10 next[q] = k 11 return next

 在不同的情况下,对应的next下标是不相同的,当然和个人编写代码的习惯也是有很大的关系,

下面的代码是实现 对 子串 进行 next 的初始化的代码,

在实现中,next 和 子串 的下标 是从 0开始计算的。

 

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

int main ( )
{
    int len ;
    char S[101] ;
    int next[101] ;

    int k , i ;

    memset( S , 0 , sizeof(S) ) ;
    memset (next , 0 , sizeof (next) ) ;

    scanf("%s" , S) ;

    len = strlen(S) ;

    next[0] = 0 ;
    
    k = 0 ;

    for ( i = 1 ; i < len ; i++ )
    {
        while ( k >0 && S[k] != S [i] )
        {
            k = next[k] ;
        }
        if ( S[k] == S[i] )
        {
           k = k+1 ;
        }

        next[i] = k ;
    }

    for ( i = 0 ; i < len ; i++ ) 
    {
        printf("next[%d] : %d\n", i,next[i]) ;
    }

    return 0 ;
}

 

而下面的代码实现的是, 基于KMP 算法的 对字符串的匹配 代码。

LZ 并没有将 next 数组初始化操作写成一个 单独的函数,而是将它作为 整个main 函数中的一个处理步骤。

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

int main ()
{
    int len_s , len_t ;
    char S[101], T[101] ;
    int next[101]  ;

    int k, i ;


    scanf("%s %s", S , T) ;

    len_s = strlen(S) ;
    len_t = strlen(T) ;

    memset(next, 0 , sizeof(next) ) ;

//initial next array
    
    next[0] = 0 ;

    for (k = 0 , i = 1 ; i < len_s ; i++ )
    {
        while ( k > 0 && S[k] != S[i] )
            k = next[k] ;
        if ( S[k] == S[i] )
            k = k+1 ;
        next[i] = k ;
    }

//show next 
    for ( i = 0 ; i  < len_s ; i++ )
    {
        printf(" next %d \n", next[i]);
    }


 //Main match 

    for (k= 0 , i = 0 ; i < len_t ; i++ )
    {
        while ( k > 0 && S[k] != T [i] )
            k = next[k] ;
        if ( S[k] == T[i] )
            k = k+1 ;

        if ( k == len_s-1 )
        {
            printf("YES\n") ;
            break ;
        }
    }

    if (i >= len_t )
        printf("NO\n") ;
    return 0 ;
}

 -------------------------ACM_KMP-----------------------------------

All in All
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 26253 Accepted: 10650

Description

You have devised a new encryption technique which encodes a message by inserting between its characters randomly generated strings in a clever way. Because of pending patent issues we will not discuss in detail how the strings are generated and inserted into the original message. To validate your method, however, it is necessary to write a program that checks if the message is really encoded in the final string.

Given two strings s and t, you have to decide whether s is a subsequence of t, i.e. if you can remove characters from t such that the concatenation of the remaining characters is s.

Input

The input contains several testcases. Each is specified by two strings s, t of alphanumeric ASCII characters separated by whitespace.The length of s and t will no more than 100000.

Output

For each test case output "Yes", if s is a subsequence of t,otherwise output "No".

Sample Input

sequence subsequence
person compression
VERDI vivaVittorioEmanueleReDiItalia
caseDoesMatter CaseDoesMatter

Sample Output

Yes
No
Yes
No
----------------------------IDEA-------------------------------------
可以创建两层循环:
循环1{
    接收两个字符串 于 S , T 并调用 strlen 计算出 字符串的长度 s:len_s t:len_t
  
    counter = 0 ;
   for ( i = 0 ; i < len_t ; i++ )
   {
      if ( S[counter] == T[i] )
      {
        if ( counter == len_s -1 )//is S finished?
        { 
         break ;
        
        }
        counter++ ;


      }
  }
 
    if ( counter == len_s-1 ) {printf YES break}
    if ( counter != len_s-1 ) {printf NO break }
}
    
------------------------------SRC-------------------------------------

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

int main()
{
    char S[100005],T[100005] ;
    int s, t;
    int counter ,i;

    while ( ~scanf("%s %s", S,T) )
    {
        s = strlen ( S ) ;
        t = strlen ( T ) ;
        counter = 0 ;

    
        for ( i = 0 ; i < t ; i++ )
        {
            if ( T[i] == S[counter] )
            {
                if (counter == (s-1))
                {
                    
                    break ;
                }

                counter++ ;
            }
        }
        
        printf("%d  t %d" , i, t) ;

        if ( counter == s -1 ) printf("Yes\n") ;
        else    printf("No\n") ;
    
    }
    
        return 0 ;
}

//(╰_╯)#  为毛不过呢!!

 

转载于:https://www.cnblogs.com/inuyasha1027/p/algorithm_KMP.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值