2010-10-09 4 views
0

Учитывая список наборов ...Как удалить все правильные подмножества?

var sets = new List<HashSet<int>>(numTags); 

Как я могу удалить все наборы, которые являются подмножеством другого?

Это лучший способ сделать это?

for (int i = 0; i < sets.Count; ++i) 
{ 
    for (int j = 0; j < sets.Count; ++j) 
    { 
     if (i != j && sets[i].IsProperSubsetOf(sets[j])) 
     { 
      sets.RemoveAt(i--); 
     } 
    } 
} 

Я декремент i, потому что я предполагаю, что все становится подтолкнуло вниз один после того, как получает удалено, так что я должен проверить, что слот снова.

+0

Вместо того, чтобы удалять элементы из коллекции во время итерации по ней, я бы взял набор индексов, которые нужно удалить. Затем, после итерации, удалите по индексу. Это немного менее эффективно, но это также менее вероятно вызывает неожиданные побочные эффекты. –

+0

@ Jim: Звучит разумно, но мы могли бы доказать, действительно ли это имеет побочные эффекты, а затем перестать беспокоиться об этом? Вместо того, чтобы перешагнуть проблему. В любом случае, это и решение Grozz, похоже, работают на практике. Понятно, что 'RemoveAll' был построен с учетом этого. – mpen

ответ

3
var toRemove = sets.Where(s => sets.Any(superset => s.IsProperSubsetOf(superset))).ToList(); 

foreach (var s in toRemove) 
    sets.Remove(s); 

Вам не нужно s != superset чек, вызывают никакого набора не является подмножеством самого себя. http://en.wikipedia.org/wiki/Proper_subset#proper_subset

+2

Еще лучше, используйте 'RemoveAll'. 'sets.RemoveAll (subset => sets.Any (superset => subset! = superset && subset.IsSubsetOf (superset)));' Спасибо! – mpen

+0

Нет ... Я это знаю, но я передумал, мне действительно нужен обычный старый подмножество;) – mpen