

Boyer Moore 算法是字符串匹配(模式搜索)的主要高效算法之一。
Boyer-Moore(BM)算法被认为最高效的字符串搜索算法,它由Bob Boyer和J Strother Moore于1977年设计实现。通常情况下,Boyer Moore 算法比KMP算法快3-5倍。
BM算法的精华就在于BM(text, pattern),也就是BM算法当不匹配的时候一次性可以跳过不止一个字符。即它不需要对被搜索的字符串中的字符进行逐一比较,而会跳过其中某些部分。通常搜索关键字越长,算法速度越快。它的效率来自于这样的事实:对于每一次失败的匹配尝试,算法都能够使用这些信息来排除尽可能多的无法匹配的位置。即它充分利用待搜索字符串的一些特征,加快了搜索的步骤。
BM算法实际上包含两个并行的算法(也就是两个启发策略):坏字符算法(bad-character shift)和好后缀算法(good-suffix shift)。这两种算法的目的就是让模式串每次向右移动尽可能大的距离(即上面的BM()尽可能大)。
本代码运行效果:

源代码:
using System;
 using System.Text;
 using System.Collections;
 using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
 {
     /// <summary>
     /// 字符串匹配算法(模式搜索)Boyer Moore 算法
     /// </summary>
     public static partial class PatternSearch
     {
         /// <summary>
         /// “坏字符”限制(数组大小)
         /// 处理中文,这个要大大增加!!!!
         /// </summary>
         //private static int NO_OF_CHARS = 256;
        /// <summary>
         /// “坏字符启发式”的预处理函数
         /// The preprocessing function for bad character heuristic
         /// </summary>
         /// <param name="patternCharArray"></param>
         /// <param name="badcharArray"></param>
         public static void Bad_Char_Heuristic(char[] patternCharArray, out int[] badcharArray)
         {
             badcharArray = new int[ALPHA_CODE_MAX];
             for (int i = 0; i < ALPHA_CODE_MAX; i++)
             {
                 badcharArray[i] = -1;
             }
            for (int i = 0; i < patternCharArray.Length; i++)
             {
                 badcharArray[(int)patternCharArray[i]] = i;
             }
         }
        /// <summary>
         /// 使用了“坏字符启发式”的
         /// 字符串匹配算法(模式搜索)Boyer Moore 算法
         /// A pattern searching function that uses Bad
         /// Character Heuristic of Boyer Moore Algorithm
         /// </summary>
         /// <param name="text"></param>
         /// <param name="pattern"></param>
         public static List<int> Boyer_Moore_Search(string text, string pattern)
         {
             int m = pattern.Length;
             int n = text.Length;
List<int> matchs = new List<int>();
            Bad_Char_Heuristic(pattern.ToCharArray(), out int[] badchar);
             
             int s = 0;
             while (s <= (n - m))
             {
                 int j = m - 1;
                 while (j >= 0 && pattern[j] == text[s + j])
                 {
                     j--;
                 }
                // 如果匹配串出现在当前位置
                 if (j < 0)
                 {
                     matchs.Add(s);
                    // 改变模式,使下一个文本中的字符与最后一个对齐它在匹配串中的出现。
                     // 条件s + m < n是,当匹配串出现在末端时的情况。
                     s += (s + m < n) ? m - badchar[text[s + m]] : 1;
                 }
                 else
                 {
                     // 修改匹配数值,让“坏字符”在文本中与最后一次出现的是匹配串。
                     // max函数用于确保我们得到积极的转变。
                     // 如果最后一次坏字母在匹配串中的出现位于当前角色的右侧。
                     s += Math.Max(1, j - badchar[text[s + j]]);
                 }
             }
            return matchs;
         }
     }
 }
  
-----------------------------------------------------------------------
POWER BY TRUFFER.CN
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace Legalsoft.Truffer.Algorithm
{
    /// <summary>
    /// 字符串匹配算法(模式搜索)Boyer Moore 算法
    /// </summary>
    public static partial class PatternSearch
    {
        /// <summary>
        /// “坏字符”限制(数组大小)
        /// 处理中文,这个要大大增加!!!!
        /// </summary>
        //private static int NO_OF_CHARS = 256;
        /// <summary>
        /// “坏字符启发式”的预处理函数
        /// The preprocessing function for bad character heuristic
        /// </summary>
        /// <param name="patternCharArray"></param>
        /// <param name="badcharArray"></param>
        public static void Bad_Char_Heuristic(char[] patternCharArray, out int[] badcharArray)
        {
            badcharArray = new int[ALPHA_CODE_MAX];
            for (int i = 0; i < ALPHA_CODE_MAX; i++)
            {
                badcharArray[i] = -1;
            }
            for (int i = 0; i < patternCharArray.Length; i++)
            {
                badcharArray[(int)patternCharArray[i]] = i;
            }
        }
        /// <summary>
        /// 使用了“坏字符启发式”的
        /// 字符串匹配算法(模式搜索)Boyer Moore 算法
        /// A pattern searching function that uses Bad
        /// Character Heuristic of Boyer Moore Algorithm
        /// </summary>
        /// <param name="text"></param>
        /// <param name="pattern"></param>
        public static List<int> Boyer_Moore_Search(string text, string pattern)
        {
            int m = pattern.Length;
            int n = text.Length;
            List<int> matchs = new List<int>();
            Bad_Char_Heuristic(pattern.ToCharArray(), out int[] badchar);
            
            int s = 0;
            while (s <= (n - m))
            {
                int j = m - 1;
                while (j >= 0 && pattern[j] == text[s + j])
                {
                    j--;
                }
                // 如果匹配串出现在当前位置
                if (j < 0)
                {
                    matchs.Add(s);
                    // 改变模式,使下一个文本中的字符与最后一个对齐它在匹配串中的出现。
                    // 条件s + m < n是,当匹配串出现在末端时的情况。
                    s += (s + m < n) ? m - badchar[text[s + m]] : 1;
                }
                else
                {
                    // 修改匹配数值,让“坏字符”在文本中与最后一次出现的是匹配串。
                    // max函数用于确保我们得到积极的转变。
                    // 如果最后一次坏字母在匹配串中的出现位于当前角色的右侧。
                    s += Math.Max(1, j - badchar[text[s + j]]);
                }
            }
            return matchs;
        }
    }
}









