调用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));
}
}
}
}

来源:https://www.cnblogs.com/ornithopter/p/3794166.html