C#binarysearch由T </t>的成员列出<t>

时间:2010-04-02 09:04:24

标签: c# search class binary member

我有一个基类Event,其DateTime成员TimeStamp。 许多其他事件类将源于此。

我希望能够快速搜索事件列表,所以我想使用二进制搜索。

(列表数据按时间戳排序,但同时发生的事件可能存在重复的时间戳)

所以我开始写这样的东西:

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的成员进行搜索 - TimeStamp

什么是接近这个的好方法?

5 个答案:

答案 0 :(得分:1)

我认为您已经使用comparer功能正确的方式。它通过比较它们的日期来比较两个T。

要处理inFromTime BinarySearch参数,您可以创建一个具有正确TimeStamp的虚拟事件,并将该虚拟传递给BinarySearch

另外,只是为了确保:列表是否按时间字段排序?否则binarysearch将无效。

修改

这个问题比我想象的要复杂得多。可以帮助您的解决方案是:

  • 创建一个适配器类,将EventList公开为IList。
  • 在IList上使用BinarySearch扩展方法进行搜索。

不幸的是没有内置BinarySearch extension method,所以你必须自己编写。如果您编写自己的搜索,将其放入扩展方法可能不值得花费额外的努力。在这种情况下,只需在EventList类中自己实现自定义BinarySearch算法,就可以做到最好。

另一种选择是,如果有一种形式的BinarySearch接受了一个从T中提取相关密钥的代理,但是也没有。

答案 1 :(得分:0)

最简单的方法是定义一个实现IComparer<T>的小助手类。

public class CompUtil : IComparer<T> {
  public int Compare(T left, T right) { 
    return left.TimeStamp.CompareTo(right.TimeStamp);
  }
}

然后您可以按如下方式使用它

int index = this.BinarySearch(inFromTime, new CompUtil());

答案 2 :(得分:0)

如果您的Event类包含要排序的属性,那么您的方法就可以了。然后,编译器可以验证传入的T是什么,它将继承自Event并包含DateTime属性。如果Event不包含DateTime属性,您可能希望将其添加到事件,或将T约束为更具体的类型,其中包含搜索所需的属性。

请务必确保在应用BinarySearch之前对列表进行排序。

答案 3 :(得分:0)

public class EventList<TEvent, TData>
   : List<TEvent> where TEvent : Event, TData: DataTime
{
   class Comparer : IComparer<TData> { } // as JaredPar mentioned above

   public IEnumerable<TEvent> EventsBetween(TData from, TData to) { }
}

答案 4 :(得分:0)

也许您可以考虑使用SortedList作为基类而不是List。然后,您可以使用IndexOfKey方法搜索指定的TimeStamp。该方法进行二分查找。