C# 二进制搜索列表由 T 的成员
我有一个带有 DateTime
成员 TimeStamp
的基类 Event
。 许多其他事件类将从中派生。
我希望能够快速搜索事件列表,因此我想使用二分搜索。
(列表数据按时间戳排序,但同时发生的事件可能有重复的时间戳)
所以我开始写这样的东西:
public class EventList<T> : List<T> where T : Event
{
private IComparer<T> comparer = (x, y) => Comparer<DateTime>.Default.Compare(x.TimeStamp, y.TimeStamp);
public IEnumerable<T> EventsBetween(DateTime inFromTime, DateTime inToTime)
{
// Find the index for the beginning.
int index = this.BinarySearch(inFromTime, comparer);
// BLAH REST OF IMPLEMENTATION
}
}
问题是 BinarySearch 只接受 T (所以 - 一个 Event 类型)作为参数,而我想基于 T 的成员 - 时间戳进行搜索。
解决这个问题的好方法是什么?
I have a baseclass Event
with a DateTime
member TimeStamp
.
Lots of other event-classes will derive from this.
I want to be able to search a list of events fast, so I'd like to use a binary search.
(The list-data is sorted on timestamp, but there might be duplicate timestamps for events that occurred simultaneously)
So I started out writing something like this :
public class EventList<T> : List<T> where T : Event
{
private IComparer<T> comparer = (x, y) => Comparer<DateTime>.Default.Compare(x.TimeStamp, y.TimeStamp);
public IEnumerable<T> EventsBetween(DateTime inFromTime, DateTime inToTime)
{
// Find the index for the beginning.
int index = this.BinarySearch(inFromTime, comparer);
// BLAH REST OF IMPLEMENTATION
}
}
The problem is that the BinarySearch only accepts T (so - an Event
type) as parameter, while I want to search based on a member of T - the TimeStamp.
What would be a good way to approach this ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为您的
comparer
功能已经走在正确的道路上。它通过比较两个 T 的日期来进行比较。要处理
BinarySearch
的inFromTime
参数,您可以创建一个具有正确TimeStamp
的虚拟事件,并将该虚拟事件传递给BinarySearch.
另外,只是为了确保:列表是否按时间字段排序?否则二分查找将无法工作。
编辑
这个问题比我最初想象的更复杂。一个对您有帮助的解决方案是:
不幸的是,没有内置的 BinarySearch 扩展方法,所以你必须自己写。如果您编写自己的搜索,则可能不值得花费额外的精力将其放入扩展方法中。在这种情况下,您自己在 EventList 类中实现自定义 BinarySearch 算法可能是最好的选择。
另一种选择是,如果有一种 BinarySearch 接受从 T 中提取相关密钥的委托,但这也不可用。
I think that you already are on the right way with your
comparer
function. It compares two T's by comparing the dates of them.To handle the
inFromTime
parameter toBinarySearch
you can create a dummy Event which has the correctTimeStamp
and pass that dummy toBinarySearch
.Also, just to make sure: Is the list sorted on the time field? Otherwise binarysearch won't work.
Edit
This problem is more complex than I first thought. A solution that would help you is:
Unfortunately there is no built in BinarySearch extension method, so you will have to write your own. In case you write your own search it might not be worth the extra effort to put it in an extension method. In that case just implementing a custom BinarySearch algorithm yourself in your EventList class is probably the best you can do.
Another option would be if there was a form of BinarySearch that accepted a delegate that extracts the relevant key from T, but that is not available either.
最简单的方法是定义一个实现
IComparer
的小帮助器类。然后您可以按如下方式使用它
The easiest way is to define a small helper class which implements
IComparer<T>
.You can then use it as follows
如果您的
Event
类包含您想要排序的属性,那么您的方法就可以了。然后,编译器可以验证传入的任何 T 是否都将从 Event 继承并包含 DateTime 属性。如果Event
不包含 DateTime 属性,您可能希望将其添加到事件中,或将 T 限制为更具体的类型,其中包含搜索所需的属性。请记住在应用二进制搜索之前确保您的列表已排序。
If your
Event
class contains the property you want to sort on, your approach will be fine. The compiler can then verify that whatever T is being passed in, it will inherit from Event and contain the DateTime property. IfEvent
does not contain the DateTime property, you would probably want to add it to event, or constrain T to be a more specific type, which contains the property needed for your search.Remember to make sure your list is sorted before applying BinarySearch.
也许您可以考虑使用 SortedList 作为基类而不是列表。然后,您可以使用 IndexOfKey 方法搜索指定的时间戳。该方法进行二分搜索。
Maybe you could consider using SortedList as base class instead of List. You could then use IndexOfKey method to search for a specified TimeStamp. That method does a binary search.