Вопрос

У меня есть реализация очереди приоритетов на 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.

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

Это было полезно?

Решение

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top