Я не уверен, что стоит пытаться оптимизировать очень далеко. Вы могли бы реализовать некоторый бинарный поиск с этим, но его эффективность была бы довольно ограниченной. Сколько элементов мы говорим?
Без сопоставленных элементов в цели
При условии, что списки отсортированы, и в target
нет элементов, которые не могут быть сопоставлены с source
:
static List<string>[] FindMatches(string[] source, string[] target)
{
// Initialize array to hold results
List<string>[] matches = new List<string>[source.Length];
for (int i = 0; i < matches.Length; i++)
matches[i] = new List<string>();
int s = 0;
for (int t = 0; t < target.Length; t++)
{
while (!MatchName(source[s], target[t]))
{
s++;
if (s >= source.Length)
return matches;
}
matches[s].Add(target[t]);
}
return matches;
}
С непревзойденными элементами
Если существует вероятность того, что элементы, существующие в target
, не будут совпадать с source
, вышеприведенное будет нарушено (если элементы не находятся в конце цели). Чтобы исправить это, было бы лучше пойти с другой реализацией для сравнения. Вместо логического значения нам нужно, чтобы он возвращал «меньше чем», «равно» или «больше чем», как Comparer при использовании в сортировке:
static List<string>[] FindMatches(string[] source, string[] target)
{
// Initialize array to hold results
List<string>[] matches = new List<string>[source.Length];
for (int i = 0; i < matches.Length; i++)
matches[i] = new List<string>();
int s = 0;
for (int t = 0; t < target.Length; t++)
{
int m = CompareName(source[s], target[t]);
if (m == 0)
{
matches[s].Add(target[t]);
}
else if (m > 0)
{
s++;
if (s >= source.Length)
return matches;
t--;
}
}
return matches;
}
static int CompareName(string source, string target)
{
// Whatever comparison you need here, this one is really basic :)
return target[0] - source[0];
}
В остальном они в основном одинаковы. Как видите, вы перебираете целевые элементы один раз, продвигая индекс к исходному массиву, когда вы больше не находите совпадения.
Если количество исходных элементов ограничено, возможно, стоит поискать немного умнее. Если количество исходных элементов также велико, предполагаемая выгода от этого уменьшится.
Опять же, первый алгоритм занимает 0,18 секунды с 1 миллионом целевых элементов на моей машине в режиме отладки. Второй еще быстрее ( 0,03 секунды ), но это из-за более простого сравнения, которое делается. Возможно, вам придется сравнивать все до первого символа пробела, делая его значительно медленнее.