LoginSignup
7
10

More than 5 years have passed since last update.

int[]とかbyte[]とかでも文字列検索というかIndexOfが欲しいからQuick Search書いた

Last updated at Posted at 2014-12-16

なければ作る。

説明、書いたほうがストック数は伸びるんだろうなあ……

(説明を読みたい人はわっふるわっふるとコメントしてください)

参照したサイト:Algorithms with Python / 文字列の探索

using System.Collections.Generic;

public static class ArrayEx
{
    public static int IndexOf<T>(this T[] source, T[] pattern)
    {
        var table = MakeTable(pattern);
        return QuickSearch(table, source, pattern);
    }

    private static Dictionary<T, int> MakeTable<T>(T[] pattern)
    {
        var table = new Dictionary<T, int>(pattern.Length);
        for (var i = 0; i < pattern.Length; i++)
        {
            table[pattern[i]] = pattern.Length - i;
        }
        return table;
    }

    private static int QuickSearch<T>(Dictionary<T, int> table, T[] source, T[] pattern)
    {
        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
        var sLen = source.Length;
        var pLen = pattern.Length;
        for (var sPos = 0; sPos <= sLen - pLen; sPos += Shift(table, pLen, source[sPos + pLen]))
        {
            var pPos = 0;
            for (; pPos < pLen; pPos++)
                if (!comparer.Equals(source[sPos + pPos], pattern[pPos]))
                    break;
            if (pPos == pLen)
                return sPos; // found
            if (sPos == sLen - pLen)
                break;
        }
        return -1; // not found
    }

    private static int Shift<T>(Dictionary<T, int> table, int patternLength, T next)
    {
        int s;
        return (table.TryGetValue(next, out s)) ? s : patternLength + 1;
    }
}

7
10
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10