Быстрый способ узнать, являются ли две интерфейс ICollection<T> коллекции содержат одни и те же объекты
-
08-07-2019 - |
Вопрос
Какой самый быстрый способ выяснить, являются ли два ICollection<T>
коллекции содержат точно такие же записи?Грубая сила понятна, мне было интересно, есть ли более элегантный метод.
Мы используем C # 2.0, поэтому, пожалуйста, никаких методов расширения, если это возможно!
Редактировать:ответ был бы интересен как для упорядоченных, так и для неупорядоченных коллекций, и, надеюсь, был бы разным для каждой из них.
Решение
используйте C5
http://www.itu.dk/research/c5/
" Проверьте, все ли предметы из прилагаемой коллекции находятся в этой сумке
(подсчет кратностей).
Предметы, которые нужно искать.
Значение true, если все элементы найдены. "
[Tested]
public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T
{
HashBag<T> res = new HashBag<T>(itemequalityComparer);
foreach (T item in items)
if (res.ContainsCount(item) < ContainsCount(item))
res.Add(item);
else
return false;
return true;
}
Другие советы
Сначала сравните .Считать из коллекций, если они имеют одинаковое количество, выполните сравнение методом перебора для всех элементов.Наихудший сценарий - это O (n).Это в том случае, если порядок элементов должен быть одинаковым.
Во втором случае, когда порядок не совпадает, вам нужно использовать словарь для хранения количества элементов, найденных в коллекциях:Вот возможный алгоритм
- Сравните количество коллекций :верните false, если они разные
- Повторите первую коллекцию
- Если элемент не существует в словаре, то добавьте запись с ключом = Item, значением = 1 (количество)
- Если элемент существует, увеличьте количество элементов в словаре;
- Повторите вторую коллекцию
- Если элемента нет в словаре, то then возвращает false
- Если элемент находится в словаре, уменьшите количество для элемента
- Если count == 0, то элемент удаления;
- возвращает словарь.Количество == 0;
Для упорядоченных коллекций вы можете использовать метод расширения SequenceEqual ()
, определенный System.Linq.Enumerable
:
if (firstCollection.SequenceEqual(secondCollection))
Вы имеете в виду одинаковые записи или одинаковые записи в одном и том же порядке?
В любом случае, при условии, что вы хотите сравнить, если они содержат одинаковые записи в одном и том же порядке, "грубая сила" действительно ваш единственный вариант в C # 2.0. Я знаю, что вы подразумеваете под не элегантным, но если само атомарное сравнение равно O (1), весь процесс должен быть в O (N), что не так , что плохо.
Если записи должны быть в одном и том же порядке (помимо того, что они одинаковы), то я предлагаю - в качестве оптимизации - вы итерируете обе коллекции одновременно и сравниваете текущую запись в каждой коллекции. В противном случае, грубая сила - путь.
Да, и еще одно предложение - вы можете переопределить Equals для класса коллекции и реализовать там элементы равенства (хотя это зависит от вашего проекта).
Опять же, используя библиотеку C5, имеющую два набора, вы можете использовать:
C5.ICollection<T> set1 = C5.ICollection<T> (); C5.ICollection<T> set2 = C5.ICollecton<T> (); if (set1.UnsequencedEquals (set2)) { // Do something }
Библиотека C5 включает эвристику, которая на самом деле сначала тестирует неупорядоченные хеш-коды двух наборов (см. C5.ICollection < T > .GetUnsequencedHashCode ()
), так что если хэш-коды двух наборы являются неравными, для проверки на равенство не нужно перебирать каждый элемент.
Также следует отметить, что C5.ICollection < T >
наследуется от System.Collections.Generic.ICollection < T >
, поэтому вы можете использовать реализации C5 все еще используя интерфейсы .NET (хотя у вас есть доступ к меньшему количеству функций через скупые интерфейсы .NET).
Грубая сила берет O (n) - сравнивая все элементы (при условии, что они отсортированы), что, я думаю, будет лучшим, что вы могли бы сделать - если только не существует какого-либо свойства данных, облегчающего его.
Я предполагаю, что в случае не отсортированного, его O (n * n). Р>
В этом случае я думаю, что решение, основанное на сортировке слиянием , вероятно, поможет . р>
Например, не могли бы вы смоделировать его так, чтобы была только одна коллекция? Или 3 набора, один для тех, кто только в коллекции A, один только для B и для обоих - так что, если только A и B только пусты - тогда они одинаковы ... Я, вероятно, ухожу по совершенно неправильной касательной здесь ...