鉴于:
List<Tuple<DateTime, int>>
提供的列表按DateTime
值descending
排序。
如何使用.BinarySearch()
方法查找DateTime
为>=
的值的最小索引而不是指定值?
EG,值:
[0] = 29th Jan
[1] = 25th Jan
[2] = 20th Jan
[3] = 10th Jan
[4] = 3rd Jan
搜索结果如下:
1st Jan = return 4
5th Jan = return 3
28th Jan = return 0
1st Feb = return something else indicating nothing found (eg -1 or null)
答案 0 :(得分:4)
由于您的列表的排序方式与BinarySearch
所期望的相反,因此您的比较方法需要返回日期对比结果的倒数:
class TupleCompare : IComparer<Tuple<DateTime,int>> {
public static readonly TupleCompare Instance = new TupleCompare();
public int Compare(Tuple<DateTime,int> x, Tuple<DateTime,int> y) {
return -x.Item1.CompareTo(y.Item1); // Note the negative here
}
}
使用此比较器,调用BinarySearch
,检查其值是否为负,反转其位,然后减去1:
DateTime myDate = ... // desired date
int index = list.BinarySearch(Tuple.Create(myDate, 0), TupleCompare.Instance);
if (index < 0) {
var res = ~index-1;
} else {
Console.WriteLine("Exact match at index {0}", index);
}
答案 1 :(得分:1)
使用现有的二进制搜索算法实际上有一个技巧。降序只需使用负值。
List<DateTime> list = new List<DateTime>();
list.Add(Convert.ToDateTime("29 Jan"));
list.Add(Convert.ToDateTime("25 Jan"));
list.Add(Convert.ToDateTime("20 Jan"));
list.Add(Convert.ToDateTime("10 Jan"));
list.Add(Convert.ToDateTime("3 Jan"));
var comparer = Comparer<DateTime>.Create((x, y) => -x.CompareTo(y)); // notice negative
var search = Convert.ToDateTime("2 Jan");
var find = list.BinarySearch(search, comparer);
if (find < 0) find = ~find - 1; // minus 1 because ordered by descending
Console.WriteLine(find);
答案 2 :(得分:0)
请尝试以下操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Data;
using System.Xml.Serialization;
namespace ConsoleApplication20
{
class Program
{
static void Main(string[] args)
{
List<Tuple<DateTime, int>> list = new List<Tuple<DateTime,int>>() {
new Tuple<DateTime,int>(new DateTime(2018, 1,29),0),
new Tuple<DateTime,int>(new DateTime(2018, 1,25),1),
new Tuple<DateTime,int>(new DateTime(2018, 1,20),2),
new Tuple<DateTime,int>(new DateTime(2018, 1,10),3),
new Tuple<DateTime,int>(new DateTime(2018, 1,3),4)
};
List<DateTime> searchDates = new List<DateTime>() { new DateTime(2018, 1, 1), new DateTime(2018, 1, 5), new DateTime(2018, 1, 28), new DateTime(2018, 2, 1) };
foreach(DateTime date in searchDates)
{
int results = BinarySearch(list, date);
Console.WriteLine("Input Date : '{0}', index : '{1}'", date.ToShortDateString(), results);
}
Console.ReadLine();
}
static int BinarySearch(List<Tuple<DateTime, int>> list, DateTime date)
{
var results = list.Select(x => new { diff = (x.Item1 - date).Days, index = x.Item2 }).Where(x => x.diff >= 0).OrderBy(x => x.diff).FirstOrDefault();
return results == null ? -1 : results.index;
}
}
}