なければ作る。
説明、書いたほうがストック数は伸びるんだろうなあ……
(説明を読みたい人はわっふるわっふるとコメントしてください)
参照したサイト: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;
}
}