Кажется, что много работы на «сотню» имен. Выполнение линейного поиска в списке сотен имен будет очень быстрым. Теперь, если вы говорите сотни тысяч или миллионы ...
В любом случае вы можете ускорить это, используя словарь. Вы можете предварительно обработать данные в словаре, ключи которого представляют собой комбинацию символа и положения, а значения - это слова, которые содержат этот символ в этой позиции. Например, если бы вы были индексом «сортир» и «Иосифом», вы бы:
{'j',0},{"john","jospeh"}
{'o',1},{"john","joseph"}
{'h',2},{"john"}
{'n',3},{"john}
{'s',2},{"joseph"}
{'e',3},{"joseph"}
{'p',4},{"joseph"}
{'h',5},{"joseph"}
Теперь предположим, что вы дали маску «джо ....» (точки являются «Дон» t care "). Вы бы превратить это в двух ключах:
{'j',0}
{'o',1}
Вы запросить словарь для списка слов, который имеет «J» с индексом 0. Тогда вы запрашиваете словарь для списка слов, которые есть «о» в index 1. Затем вы пересекаете списки, чтобы получить результат.
Это простой инвертированный указатель, но скорее на символ, чем на слово.
Списки сами будут стоить вам всего O (m * n) пространства, где m - общее количество слов, а n - средняя длина слова в символах.Максимально количество записей в словаре будет 26 * max_word_length. На практике это, вероятно, будет намного меньше.
Если вы делаете значения a HashSet<string>
, а не List<string>
, пересечение будет проходить намного быстрее. Тем не менее, это увеличит объем памяти.
Это должно быть быстрее линейного поиска, если ваши маски содержат только несколько символов. Чем дольше маска, тем больше списков вам придется пересекать.
Для словаря ключ, я бы рекомендовал:
public struct Key
{
public char KeyChar;
public int Pos;
public override int GetHashCode()
{
return (int)KeyChar + Pos << 16;
}
public override bool Equals(object obj)
{
if (!obj is Key) return false;
var other = (Key)obj;
return KeyChar == other.KeyChar && Pos == other.Pos;
}
}
Так ваш словарь будет Dictionary<Key, HashSet<string>>
.
Самый быстрый способ - использовать хэш. Словарь имеет встроенный хэш на ключах, поэтому вы можете либо создать собственный хэш, либо использовать словарь. – jdweng
@jdweng тоже сохраняет порядок? – theonlygusti
Какие модели вы хотите совместить? Префиксные запросы довольно легко индексировать, например, но если вы хотите поддерживать общие шаблоны, я боюсь, что вы не сможете сделать лучше, чем O (n) (т. Е. Линейное сканирование) – BlackBear