Вопрос о чрезмерной реализации IndexOf - PullRequest
1 голос
/ 29 декабря 2008

У меня есть реализация очереди приоритетов в C #, в которую я хочу добавить метод .IndexOf.

Однако, поскольку очередь приоритетов на самом деле не связана с порядком самих значений (то есть, если бы я просто взял все значения, не обращая внимания на их приоритеты, они не обязательно имели бы какой-либо порядок вообще). ), только их приоритет, у меня нет никаких критериев для универсального типа T очереди приоритетов, то есть я не указываю, что они должны иметь некоторый внутренний порядок или сопоставимость .

Таким образом, когда я пришел к реализации .IndexOf(T value), у меня возникла небольшая проблема.

Есть ли стандарт в том, что / как я должен это реализовать? Сначала я думал просто использовать EqualityComparer<T>.Default, чтобы понять, нашел я value или нет, но в наши дни существует множество подобных типов.

Например, вот что я придумал, чтобы покрыть мою основу, но это кажется излишним:

  • public Int32 IndexOf(T value) (внутренне вызывает одного из других с ClassThatImplementsInterface.Default)
  • public Int32 IndexOf(T value, IComparer<T> comparer)
  • public Int32 IndexOf(T value, IEqualityComparer<T> comparer)
  • public Int32 IndexOf(T value, IEquatable<T> comparer)
  • public Int32 IndexOf(T value, Predicate<T> predicate)

Что ты делаешь? Отмечая это как субъективное и вики, так как это больше опрос общественного мнения, чем что-либо еще.

Перечитывая свой вопрос, я полагаю, что могу просто использовать тот, у которого нет компаратора, а затем добавить версию предиката, так что пользователь этого класса может вызывать практически все.

Также обратите внимание, что я также могу сделать pq[index], чтобы получить элемент, который содержит и приоритет, и само значение, так что я мог бы вообще обойтись без IndexOf, но я также хотел бы иметь методы, которые говорит изменить приоритет значения X на приоритет P , что потребует некоторой формы IndexOf / search для внутреннего использования. И поэтому я также хотел бы избежать сотых перегрузок всех этих методов.


Ответ на комментарий : Да, очередь с приоритетами основана на куче.

По сути, два класса определены так:

public class Heap<T> : IEnumerable<T>, ICloneable { ... }
public class PriorityQueue<T> : Heap<PriorityQueueElement<T>> { ... }

PriorityQueueElement - это простая неизменяемая структура со свойствами Priority и Value.

Ответ на предстоящий комментарий : Поскольку очередь приоритетов основана на куче, «интересное свойство» заключается в том, что изменение приоритета значения через его индекс означает, что впоследствии значение не будет обязательно быть по этому показателю. Я намереваюсь просто задокументировать это, поскольку в некоторых случаях я предвижу необходимость независимых операций определения местоположения / изменения приоритета.

1 Ответ

2 голосов
/ 29 декабря 2008

Я бы сделал сравнение необязательным параметром конструктора; это сравнимо с тем, как такие вещи, как Dictionary<,>, SortedList<,> и т. д. позволяют указать механизм сравнения.

Принимает ли IComparer<T> или IEqualityComparer<T> зависит от того, собираетесь ли вы сортировать данные или просто искать совпадение на равенство; если совпадение, то вам понадобится что-то вроде IEqualityComparer<T>. К сожалению, так как у этого есть 2 метода (GetHashCode() и Equals()), нет прямой версии этого делегата, кроме, возможно, Predicate<T> или Func<T,T,bool>.

Для конструктора по умолчанию я бы передал [Equality]Comparer<T>.Default.

...