zoukankan      html  css  js  c++  java
  • 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));
                }
    
            }
        }
    }

  • 相关阅读:
    《那些年,我们拿下FPGA》做笔记
    三种初始化
    hdu4417 Super Mario 树阵离线/划分树
    【设计模式】文章摘要 查找联系人控件
    STL set
    阐述 QUEST CENTRAL FOR DB2 八罪
    使用线程执行堆栈StackTraceElement设计Android日志模块
    苹果iOS苹果公司的手机用户都有权索赔
    Android 4.4 沉浸式透明状态栏与导航栏
    常见的几种RuntimeException
  • 原文地址:https://www.cnblogs.com/ornithopter/p/3794166.html
Copyright © 2011-2022 走看看