• 一份开源的BM算法


    mstring.h

     1 /*
     2 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
     3 **
     4 ** This program is free software; you can redistribute it and/or modify
     5 ** it under the terms of the GNU General Public License as published by
     6 ** the Free Software Foundation; either version 2 of the License, or
     7 ** (at your option) any later version.
     8 **
     9 ** This program is distributed in the hope that it will be useful,
    10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 ** GNU General Public License for more details.
    13 **
    14 ** You should have received a copy of the GNU General Public License
    15 ** along with this program; if not, write to the Free Software
    16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    17 */
    18 
    19 /* $Id: mstring.h,v 1.5 2003/10/20 15:03:20 chrisgreen Exp $ */
    20 
    21 #ifndef __MSTRING_H__
    22 #define __MSTRING_H__
    23 
    24 /*  I N C L U D E S  ******************************************************/
    25 #include <stdio.h>
    26 #include <stdlib.h>
    27 #include <string.h>
    28 #include <ctype.h>
    29 
    30 
    31 
    32 
    33 /*  P R O T O T Y P E S  *************************************************/
    34 class BMSearch
    35 {
    36 public:
    37     BMSearch()
    38     {
    39         skip = NULL;
    40         shift = NULL;
    41     }
    42     ~BMSearch();
    43     int Match(const char* pBuf, int nBufLen, const char* ptrn, int nLen, bool bOneTimeFlag);
    44 private:
    45     int mSearch(const char *buf, int blen, const char *ptrn, int plen, int *skip, int *shift, bool bOneTimeFlag);
    46     int *make_skip(const char *ptrn, int plen);
    47     int *make_shift(const char *ptrn, int plen);
    48 
    49     int* skip;
    50     int* shift;
    51 
    52 };
    53 
    54 
    55 #endif  /* __MSTRING_H__ */

    mstring.cpp

      1 #include <stdafx.h>
      2 #include "mstring.h"
      3 BMSearch::~BMSearch()
      4 {
      5     if (skip)
      6     {
      7         free(skip);
      8         skip = NULL;
      9     }
     10     if (shift)
     11     {
     12         free(shift);
     13         shift = NULL;
     14     }
     15 }
     16 int BMSearch::Match(const char* pBuf, int nBufLen, const char* ptrn, int nLen, bool bOneTimeFlag)
     17 {
     18     if (skip)
     19     {
     20         free(skip);
     21         skip = NULL;
     22     }
     23     if (shift)
     24     {
     25         free(shift);
     26         shift = NULL;
     27     }
     28 
     29     if (NULL == pBuf || 
     30         NULL == ptrn || 
     31         nBufLen <=0 ||
     32         nLen <= 0
     33         )
     34     {
     35         return 0;
     36     }
     37 
     38     skip = make_skip(ptrn, nLen);
     39     shift = make_shift(ptrn, nLen);
     40 
     41     if (NULL == skip || NULL == shift)
     42         return 0;
     43 
     44     return mSearch(pBuf, nBufLen, ptrn, nLen, skip, shift, bOneTimeFlag);
     45 
     46 
     47 }
     48 /****************************************************************
     49  *
     50  *  Function: make_skip(char *, int)
     51  *
     52  *  Purpose: Create a Boyer-Moore skip table for a given pattern
     53  *
     54  *  Parameters:
     55  *      ptrn => pattern
     56  *      plen => length of the data in the pattern buffer
     57  *
     58  *  Returns:
     59  *      int * - the skip table
     60  *
     61  ****************************************************************/
     62 int * BMSearch::make_skip(const char *ptrn, int plen)
     63 {
     64     int *skip = (int *) malloc(256 * sizeof(int));
     65     int *sptr = &skip[256];
     66 
     67     if (skip == NULL)
     68         return NULL;
     69 
     70     while(sptr-- != skip)
     71         *sptr = plen + 1;
     72 
     73     while(plen != 0)
     74         skip[(unsigned char) *ptrn++] = plen--;
     75 
     76     return skip;
     77 }
     78 
     79 
     80 
     81 /****************************************************************
     82  *
     83  *  Function: make_shift(char *, int)
     84  *
     85  *  Purpose: Create a Boyer-Moore shift table for a given pattern
     86  *
     87  *  Parameters:
     88  *      ptrn => pattern
     89  *      plen => length of the data in the pattern buffer
     90  *
     91  *  Returns:
     92  *      int * - the shift table
     93  *
     94  ****************************************************************/
     95 int *BMSearch::make_shift(const char *ptrn, int plen)
     96 {
     97     int *shift = (int *) malloc(plen * sizeof(int));
     98     int *sptr = shift + plen - 1;
     99     const char *pptr = ptrn + plen - 1;
    100     char c;
    101 
    102     if (shift == NULL)
    103         return NULL;
    104 
    105      c = ptrn[plen - 1];
    106 
    107     *sptr = 1;
    108 
    109     while(sptr-- != shift)
    110     {
    111         const char *p1 = ptrn + plen - 2, *p2, *p3;
    112 
    113         do
    114         {
    115             while(p1 >= ptrn && *p1-- != c);
    116 
    117             p2 = ptrn + plen - 2;
    118             p3 = p1;
    119 
    120             while(p3 >= ptrn && *p3-- == *p2-- && p2 >= pptr);
    121         }
    122         while(p3 >= ptrn && p2 >= pptr);
    123 
    124         *sptr = static_cast<int>(shift + plen - sptr + p2 - p3);
    125 
    126         pptr--;
    127     }
    128 
    129     return shift;
    130 }
    131 
    132 
    133 
    134 /****************************************************************
    135  *
    136  *  Function: mSearch(char *, int, char *, int)
    137  *
    138  *  Purpose: Determines if a string contains a (non-regex)
    139  *           substring.
    140  *
    141  *  Parameters:
    142  *      buf => data buffer we want to find the data in
    143  *      blen => data buffer length
    144  *      ptrn => pattern to find
    145  *      plen => length of the data in the pattern buffer
    146  *      skip => the B-M skip array
    147  *      shift => the B-M shift array
    148  *
    149  *  Returns:
    150  *      Integer value, 1 on success (str constains substr), 0 on
    151  *      failure (substr not in str)
    152  *
    153  ****************************************************************/
    154 int BMSearch::mSearch(const char *buf, int blen, const char *ptrn, int plen, int *skip, int *shift, bool bOneTimeFlag)
    155 {
    156     int b_idx = plen;
    157     int nCount = 0;
    158     bool bContinue = false;
    159 
    160     if(0 == blen || 0 == plen)
    161         return 1;
    162 
    163     while(b_idx <= blen)
    164     {
    165         int p_idx = plen, skip_stride, shift_stride;
    166 
    167         while(buf[--b_idx] == ptrn[--p_idx])
    168         {
    169             if(b_idx < 0)
    170                 return 0;
    171 
    172             if(p_idx == 0)
    173             {    
    174                 if (bOneTimeFlag)
    175                     return 1;
    176                 else
    177                 {
    178                     nCount++;
    179                     bContinue = true;
    180                     break;
    181                 }
    182             }
    183         }
    184 
    185         if (bContinue)
    186         {
    187             b_idx += 2*plen;
    188             bContinue = false;
    189         }
    190         else
    191         {
    192             skip_stride = skip[(unsigned char) buf[b_idx]];
    193             shift_stride = shift[p_idx];
    194 
    195             b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
    196         }
    197     }
    198 
    199     return nCount;
    200 }
  • 相关阅读:
    栈的压入、弹出序列
    HM代码分析--TAppEncoder
    HM代码分析--TAppDecoder
    包含min函数的栈
    GMOJ 6841. 【2020.11.5提高组模拟】淘淘蓝蓝之树 林
    【2020.11.5提高组模拟】总结
    dsu on tree学习总结 (树上启发式合并)
    GMOJ 6847. 【2020.11.03提高组模拟】通往强者之路
    2020.11.03【NOIP提高A组】模拟
    【2020.11.02提高组模拟】总结
  • 原文地址:https://www.cnblogs.com/whoiskevin/p/3259026.html
Copyright © 2020-2023  润新知