Вот гораздо более эффективная реализация:
static SortedDictionary<T,bool>.KeyCollection FindCommon<T> (List<List<T>> items)
{
SortedDictionary<T, bool>
current_common = new SortedDictionary<T, bool> (),
common = new SortedDictionary<T, bool> ();
foreach (List<T> list in items)
{
if (current_common.Count == 0)
{
foreach (T item in list)
{
common [item] = true;
}
}
else
{
foreach (T item in list)
{
if (current_common.ContainsKey(item))
common[item] = true;
else
common[item] = false;
}
}
if (common.Count == 0)
{
current_common.Clear ();
break;
}
SortedDictionary<T, bool>
swap = current_common;
current_common = common;
common = swap;
common.Clear ();
}
return current_common.Keys;
}
Он работает, создавая набор всех элементов, общих для всех списков, обработанных до сих пор, и сравнивая каждый список с этим набором, создавая временный набор элементов, общих для текущего списка и списка общих элементов на данный момент. Фактически O (n.m), где n - количество списков, а m - количество элементов в списках.
Пример использования:
static void Main (string [] args)
{
Random
random = new Random();
List<List<int>>
items = new List<List<int>>();
for (int i = 0 ; i < 10 ; ++i)
{
List<int>
list = new List<int> ();
items.Add (list);
for (int j = 0 ; j < 100 ; ++j)
{
list.Add (random.Next (70));
}
}
SortedDictionary<int, bool>.KeyCollection
common = FindCommon (items);
foreach (List<int> list in items)
{
list.Sort ();
}
for (int i = 0 ; i < 100 ; ++i)
{
for (int j = 0 ; j < 10 ; ++j)
{
System.Diagnostics.Trace.Write (String.Format ("{0,-4:D} ", items [j] [i]));
}
System.Diagnostics.Trace.WriteLine ("");
}
foreach (int item in common)
{
System.Diagnostics.Trace.WriteLine (String.Format ("{0,-4:D} ", item));
}
}