Boyer-Moore字符串查找算法的实现

  前段时间在园子里看到一篇讲Boyer-Moore算法原理的文章http://kb.cnblogs.com/page/176945/,写的很详细,于是在这里自己写个C语言的实现,权当是练手吧。

  基本思路是每次从模式串的最右端开始匹配,如果后缀不匹配,模式串可以快速地后移,从而快速地匹配字符串。要用一个数组right[],来存储失配时模式串的移动步数。数组的大小是256,即扩展的ASCII码表大小(即256个字符)。若对应字符不存在于模式串中,则赋值-1,否则表示字符出现在模式串中,查找失配时,模式串向右移动的步数。应该还有优化的空间,暂时没想了。

  分成两个文件,一个.h文件,一个.c文件。实现中,若匹配成功则返回第一次出现模式串的位置,若不匹配则返回模式串长度。

  N: 被搜索的字符串长度。

  M: 模式串长度。

  strsearch.h :

 1 #ifndef _STRSEARCH_H
 2 #define _STRSEARCH_H
 3 
 4 
 5 /***ASCII list length***/
 6 
 7 #define ASCII_LIST_LENGTH 256
 8 
 9 /* Interface */
10 
11 extern int BMSearch(char *dest_str,char *pattern);
12 
13 
14 #endif

  strsearch.c :

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include "strsearch.h"
 4 
 5 #ifdef _cplusplus
 6 extern "C"{
 7 #endif
 8 
 9 /*
10  ******Implementation of Boyer-Moore Algorithm******
11  *
12  * This function is to solve the string search ,and somhow we
13  * can find the position of pattern string in the dest string
14  * quickly.
15  *
16  * Copyright(c) 2013.9.6 xiaoh
17  * All rights reserved.
18  *
19  ***************************************************
20 */
21 
22 
23 /*
24  * This function is to build the jump step list for each
25  * charactor.
26  *
27 */
28 
29 void BoyerMoore(char *pattern,int right[])
30 {
31     int M = strlen(pattern);
32 
33     for(int c=0;c<ASCII_LIST_LENGTH;c++)
34         right[c] = -1;
35     for(int j=0;j<M;j++)
36         right[pattern[j]] = j;
37 }
38 
39 /*
40  * Main function of Boyer-More Search Algorithm
41  *
42 */
43 
44 int BMSearch(char *dest_str,char *pattern)
45 {
46     /*Array right: steps to move for the pattern string*/
47     int right[ASCII_LIST_LENGTH];
48 
49     BoyerMoore(pattern,right);
50 
51     int N = strlen(dest_str);
52     int M = strlen(pattern);
53 
54     int skip; //number to jump
55     for(int i=0;i<=N-M;i+=skip)
56  {
57       skip = 0;
58          for(int j=M-1;j>=0;j--)
59     {
60               if(pattern[j]!=dest_str[j+i])
61        {
62                     skip = j-right[dest_str[i+j]];//calculate the step to jump
63                     if(skip<1)
64                           skip = 1;
65                     break;
66         }
67     }
68         if(skip == 0)
69     {
70              printf("Search finished successfully.
");
71                 return i;    
72     }
73   }
74     printf("String cannot be found.
");
75     return N;
76 }
77 
78 #ifdef _cplusplus
79 }
80 #endif

   查找的最好情况时间复杂度约为O(N/M)(其实是查找完,但不匹配情况),这里需要和O(M)比较下,如果M比较大的话N/M就比较小一些;在最坏情况下,需要比较N/M组,每组比较M次,所以时间复杂度为O(N)。其查找速度确实比KMP算法还要快。

原文地址:https://www.cnblogs.com/XiaoHDeBlog/p/3308044.html