DEV Community

Niels Swimburger.NET 🍔
Niels Swimburger.NET 🍔

Posted on • Originally published at swimburger.net on

2 1

Generic Boyer–Moore–Horspool algorithm in C# .NET

Early this year, I decided to brush up on my algorithms and data structure knowledge. I took these great two courses (1, 2) on PluralSight by Robert Horvick.

To practice what I learned in this course, I decided to create generic versions of the different algorithms and data structures.

What do I mean by generic versions? These types of courses always use integers or strings to demonstrate the algorithms. Instead of using those primitive data types, I'm reimplementing the algorithms and data structures using C#'s generic type parameters.

Here's a console application with a generic method BoyerMooreHorspoolSearchSequence to perform a Boyer–Moore–Horspool algorithm search looking for a sequence of T:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var numbers = Enumerable.Range(250, 750).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;
    }
}
Enter fullscreen mode Exit fullscreen mode

By using a generic type parameter with the constraint that the type has to implement the IComparable interface, you can perform the Boyer–Moore–Horspool algorithm without knowing the exact type you are working with.

If you want to understand the logic behind the Boyer–Moore–Horspool algorithm, I recommend checking out the courses mentioned earlier. There's also a lot of other great resources out there online!

Disclaimer: This code works, but is only developed for the sake of practice. Use at your own risk or just use a sorting library. If you see some room for improvement, there most likely is, I'm all ears~

Image of Stellar post

How a Hackathon Win Led to My Startup Getting Funded

In this episode, you'll see:

  • The hackathon wins that sparked the journey.
  • The moment José and Joseph decided to go all-in.
  • Building a working prototype on Stellar.
  • Using the PassKeys feature of Soroban.
  • Getting funded via the Stellar Community Fund.

Watch the video 🎥

Top comments (0)

Quickstart image

Django MongoDB Backend Quickstart! A Step-by-Step Tutorial

Get up and running with the new Django MongoDB Backend Python library! This tutorial covers creating a Django application, connecting it to MongoDB Atlas, performing CRUD operations, and configuring the Django admin for MongoDB.

Watch full video →

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay