zoukankan      html  css  js  c++  java
  • 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算法还要快。

  • 相关阅读:
    php实现一个简单的四则运算计算器
    linux下service+命令和直接去执行命令的区别,怎么自己建立一个service启动
    mongodb
    随笔一个dom节点绑定事件
    php-fpm 启动参数及重要配置详解
    PHP的设计模式之工厂模式
    linux下mysql数据的导出和导入
    windows下mongodb安装与使用图文教程(整理)
    MySQL性能分析及explain的使用
    nginx反向代理缓存服务器的构建
  • 原文地址:https://www.cnblogs.com/XiaoHDeBlog/p/3308044.html
Copyright © 2011-2022 走看看