zoukankan      html  css  js  c++  java
  • 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
    ", 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 
    ", 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
    ") ;
                break ;
            }
        }
    
        if (i >= len_t )
            printf("NO
    ") ;
        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
    ") ;
            else    printf("No
    ") ;
        
        }
        
            return 0 ;
    }

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

  • 相关阅读:
    python笔记-列表和元组
    T-sql for xml path使用(转)
    除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效。
    VS2015 经常不出现智能提示,代码颜色也没有了
    虚拟机重新决定网卡地址时,老是报错
    模块的命令
    关闭NetworkManager的作用
    centos6上yum安装drbd(内核:2.6.32.696)
    检查硬件变化的命令kudzu
    parted分区和挂载及非交互式操作
  • 原文地址:https://www.cnblogs.com/inuyasha1027/p/algorithm_KMP.html
Copyright © 2011-2022 走看看