• Boyer-Moore (C#)


    调用ShowExample方法即可查看结果

    使用Debug配置编译可以查看详细匹配过程

    using System;
    using System.Collections.Generic;
    
    namespace Algorithms
    {
        /// <summary>
        /// An implemention of Boyer-Moore algorithm.
        /// <para/>author : Ornithopter
        /// </summary>
        class BoyerMooreSearch
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="source"></param>
            /// <param name="pattern"></param>
            /// <returns>An array of matched index</returns>
            public int[] Search(string source, string pattern)
            {
                var matchIndexes = new List<int>();
    
                // step increasment.
                var delta = 0;
    
                // prepare a map providing delta for each char in pattern string.
                var deltaMap = CreateDeltaMap(pattern);
    
                // for display.
                var indent = pattern.Length;
                DebugUtil.WriteLine(source);
    
                // start searching.
                for (int i = pattern.Length - 1; i < source.Length; i += delta)
                {
                    // for display.
                    indent += delta;
                    DebugUtil.Write(String.Format("{0}({1})", pattern.PadLeft(indent, '.'), delta));
    
                    // find next match and update delta.
                    if (FindNext(source, pattern, i, deltaMap, out delta))
                    {
                        // add to result list if found.
                        matchIndexes.Add(i - (pattern.Length - 1));
    
                        DebugUtil.Write("");
                    }
    
                    // new line.
                    DebugUtil.WriteLine();
                }
                return matchIndexes.ToArray();
            }
    
            /// <summary>
            /// Find the next matched index and update delte at the same time.
            /// </summary>
            /// <param name="source"></param>
            /// <param name="pattern"></param>
            /// <param name="start"></param>
            /// <param name="deltaMap"></param>
            /// <param name="delta"></param>
            /// <returns>true if found one, otherwise false.</returns>
            private bool FindNext(string source, string pattern, int start, int[] deltaMap, out int delta)
            {
                int i = pattern.Length - 1,
                    index = 0;
    
                // start comparing from the last char in pattern.
                while (source[start - index] == pattern[i - index])
                {
                    if (index != pattern.Length - 1)
                    {
                        index++;
                    }
                    else
                    {
                        // matchs to the end. So it's a search result.
                        delta = pattern.Length;
                        return true;
                    }
                }
    
                // found one dismatched char at (start - index), get delta from map.
                var c = source[start - index];
                delta = deltaMap[c];
    
                if (delta <= index)
                {
                    // this means the source[start] char is the last char in pattern
                    // and only appears once. So delta should be the length of pattern.
                    delta = pattern.Length;
                }
                else
                {
                    delta = delta - index;
                }
                return false;
            }
    
            int[] CreateDeltaMap(string pattern)
            {
                const int AlphabetSize = 128;
                int patternLength = pattern.Length;
                var deltaMap = new int[AlphabetSize];
    
                // initialize the map.
                for (int i = 0; i < AlphabetSize; i++)
                {
                    deltaMap[i] = patternLength;
                }
    
                // start from 0, which means any duplicated char will only have
                // the index nearest to the end.
                for (int i = 0; i < patternLength; i++)
                {
                    deltaMap[pattern[i]] = patternLength - i - 1;
                }
                return deltaMap;
            }
    
            public void ShowExample()
            {
                // source string and pattern string are in one string and splited by ','.
                var examples = new[] 
                {
                    "a b,b",
                    "AAAABAA,BA",
                    "awataa,wat",
                    "here is a simple example,ample",
                    "here is a simple example,example",
                    "AAAABAAAABAAABAAA,AB",
                    "awaaaaaaaawrwatawt,awrwatawt",
                };
                foreach (var example in examples)
                {
                    var source = example.Split(',')[0];
                    var pattern = example.Split(',')[1];
                    var result = Search(source, pattern);
                    DebugUtil.WriteLine("{0} <-> {1} : {2}", source, pattern, String.Join(",", result));
                }
    
            }
        }
    }

  • 相关阅读:
    bzoj 1179[Apio2009]Atm (tarjan+spfa)
    tarjan讲解(用codevs1332(tarjan的裸题)讲解)
    spfa
    codevs 1021 玛丽卡(spfa)
    Redis-mac安装与使用
    心血来潮整理一下STL——string
    基础算法整理(1)——递归与递推
    一道水的不能再水的中国盒子问题——小试牛刀(3)
    论久违的八数码问题——小试牛刀(2)
    8皇后及其普及(N)——小试牛刀(1)
  • 原文地址:https://www.cnblogs.com/ornithopter/p/3794166.html
Copyright © 2020-2023  润新知