0
点赞
收藏
分享

微信扫一扫

浪花 - 搜索标签前后端联调

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;
        }
    }
}
举报

相关推荐

0 条评论