关于 IndexOf 过度实现的问题
我有一个 C# 优先级队列实现,我想向其中添加 .IndexOf 方法。
然而,由于优先级队列并不真正关心值本身的顺序(也就是说,如果我只是获取所有值,忽略它们的优先级,它们根本不一定有任何顺序),只对于它们的优先级,我对优先级队列的通用类型 T 没有任何标准,也就是说,我没有指定它们需要具有某种内在顺序或可比性。
因此,当我实现 .IndexOf(T value)
时,我遇到了一个小问题。
我应该执行什么/如何执行此操作有一个标准吗? 我最初的想法只是使用 EqualityComparer
来确定我是否找到了 value
,但现在有很多类似的此类类型。
例如,以下是我想出的内容来涵盖我的基础,但这似乎有点过头了:
public Int32 IndexOf(T value)
(在内部使用ClassThatImplementsInterface.Default
调用其他之一) >)public Int32 IndexOf(T 值,IComparer
比较器) public Int32 IndexOf(T 值,IEqualityComparer
比较器) public Int32 IndexOf(T value, IEquatable
比较器) public Int32 IndexOf(T value, Predicate
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 属性。
对即将发表的评论的回应:由于优先级队列是基于堆的,因此一个“有趣的属性”是,通过索引更改值的优先级意味着之后,该值不一定会被更改。在该索引处。 我打算只是记录这一点,因为在某些情况下我预见需要独立的定位/更改优先级操作。
I have a priority queue implementation in C# that I want to add a .IndexOf method to.
However, since the priority queue doesn't really concern itself with the order of the values themselves (that is, if I were to just grab all the values, disregarding their priorities, they wouldn't necessarily have any order at all), only the priority of them, I don't have any criteria for the generic type T of the priority queue, that is, I don't specify that they need to have some intrinsic order, or comparability.
As such, when I came to implement .IndexOf(T value)
I have a minor problem.
Is there a standard in what/how I should implement this? My initial thoughts was simply to use EqualityComparer<T>.Default
to figure if I have found the value
or not, but then there are so many similar such types these days.
For instance, here's what I came up with to cover my basis, but this seems overkill:
public Int32 IndexOf(T value)
(internally calls one of the others withClassThatImplementsInterface.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)
What do you do? Marking this as both subjective and wiki as this is more of an opinion poll than anything else.
On re-reading my own question I guess I can just use the one without a comparer, and then add the predicate version, this way the user of this class can call just about anything.
Also note that I can also do pq[index]
to get hold of a item that contains both the priority and the value itself, so I could also get by without IndexOf at all, but I'd also like to have methods that says change the priority of value X to priority P, which would necessitate some form of IndexOf/search internally. And thus I'd also like to avoid having to have umpteenth overloads of all these methods as well.
Response to comment: Yes, the priority queue is based on a heap.
Basically, the two classes are defined like this:
public class Heap<T> : IEnumerable<T>, ICloneable { ... }
public class PriorityQueue<T> : Heap<PriorityQueueElement<T>> { ... }
PriorityQueueElement is a simple immutable structure with Priority and Value properties.
Response to forthcoming comment: Since the priority queue is based on a heap, an "interesting property" is that by changing the priority of a value through its index means that afterwards, the value won't necessarily be at that index. I intend to just document this as in some cases I foresee a need for independent locate/change-priority operations.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我会将比较作为可选的构造函数参数; 这类似于
Dictionary<,>
、SortedList<,>
等允许您指定比较机制的方式。是否接受
IComparer
还是IEqualityComparer
取决于您是要对数据进行排序,还是只是查找相等匹配; 如果匹配,那么您将需要类似IEqualityComparer
的内容。 不幸的是,由于它有 2 个方法(GetHashCode()
和Equals()
),所以没有直接的委托版本,除了Predicate
或Func
。对于默认构造函数,我将传入
[Equality]Comparer.Default
。I would make the comparison an optional constructor parameter; this is comparable to how things like
Dictionary<,>
,SortedList<,>
etc allow you to specify the comparison mechanism.Whether to accepts an
IComparer<T>
or anIEqualityComparer<T>
depends on whether you are going to sort the data, or just look for an equality match; if the match, then you'll need something likeIEqualityComparer<T>
. Unfortunately, since this has 2 methods (GetHashCode()
andEquals()
) there is no direct delegate version of this, except perhapsPredicate<T>
orFunc<T,T,bool>
.For the default constructor, I'd pass in the
[Equality]Comparer<T>.Default
.