Skip to content

Instantly share code, notes, and snippets.

@Swimburger
Created January 28, 2021 23:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Swimburger/f83ccd7b73df5123ace027105462b4e1 to your computer and use it in GitHub Desktop.
Save Swimburger/f83ccd7b73df5123ace027105462b4e1 to your computer and use it in GitHub Desktop.
Generic Boyer–Moore–Horspool Search Sequence in C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var numbers = Enumerable.Range(0, 1000).ToArray();
var index = BoyerMooreHorspoolSearchSequence(numbers.AsEnumerable(), new int[] { 500, 501, 502 });
Console.WriteLine("Boyer–Moore–Horspool Search Sequence:");
Console.WriteLine(index);
Console.ReadKey();
Console.Clear();
}
private static int BoyerMooreHorspoolSearchSequence<T>(IEnumerable<T> list, IEnumerable<T> needle) where T : IComparable
{
var items = list.ToArray();
var itemsLength = items.Length;
var needleArray = needle.ToArray();
var needleLength = needleArray.Length;
int shiftAmountIfMissing = needleLength;
Dictionary<T, int> badMatchTable = new Dictionary<T, int>();
for (int i = 0; i < needleLength - 1; i++)
{
badMatchTable[needleArray[i]] = needleLength - i - 1;
}
int listIndex = 0;
while (listIndex <= itemsLength - needleLength)
{
int matchIndex = needleLength - 1;
while (true)
{
if (items[listIndex + matchIndex].CompareTo(needleArray[matchIndex]) == 0)
{
matchIndex--;
}
else
{
break;
}
if (matchIndex <= 0)
{
return listIndex;
}
}
if (badMatchTable.TryGetValue(items[listIndex + needleLength - 1], out int amountToShift))
{
listIndex += amountToShift;
}
else
{
listIndex += shiftAmountIfMissing;
}
}
return -1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment