Tom*_*len 5 c# date binary-search
给定按降序排列的日期列表,此代码将找到日期的最大日期<= searchDate.
List<CurrencyHistoricExchangeRate> history = GetOrderedHistory();
foreach (var record in history)
{
if (record.Date < searchDate)
{
return record ;
}
}
Run Code Online (Sandbox Code Playgroud)
如何编写二进制搜索函数来替换此方法?我正在努力实现它,因为这样的不精确比较.
这种方法经常被调用,并且可以包含几千条记录,这就是我希望用二进制搜索替换它的原因.
给定一个排序列表,List<T>.BinarySearch实际上可以帮助您找到“等于”或“大于”您的项目的项目索引(假设是升序列表和默认比较器)。
该方法返回:
因此,首先您需要一个反向比较器,因为您的项目是反向排序的:
class CurrencyHistoricExchangeRateComparer : IComparer<CurrencyHistoricExchangeRate>
{
public int Compare(CurrencyHistoricExchangeRate x, CurrencyHistoricExchangeRate y)
{
// this is just the opposite of the default DateTime comparer
return -x.Date.CompareTo(y.Date);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您需要检查该项目是否确实找到,并对结果进行补充:
private static int FindIndex(List<CurrencyHistoricExchangeRate> list, DateTime dateTime)
{
var comparer = new CurrencyHistoricExchangeRateComparer();
var idx = list.BinarySearch(
new CurrencyHistoricExchangeRate() { Date = dateTime }, comparer);
// not found? then calculate the bitwise complement to
// get the index of the first larger element
// (this will evaluate to list.Count if there is no such element)
return (idx < 0) ? ~idx : idx;
}
Run Code Online (Sandbox Code Playgroud)
对这些结果的解释应该是这样的:
var idx = FindIndex(history, someDate);
CurrencyHistoricExchangeRate rate = null;
if (idx < history.Count)
rate = history[idx];
else
throw new InvalidOperationException($"there are no dates smaller than {someDate}");
Run Code Online (Sandbox Code Playgroud)
经过一番研究后,我想出了这个可行的解决方案:
if (history.First().Date <= date) return history.First();
var lowerIx = 0;
var upperIx = history.Count - 1;
while (true)
{
var middleIndex = lowerIx + (upperIx - lowerIx) / 2;
if (history[middleIndex].Date <= date)
{
upperIx = middleIndex;
}
else
{
lowerIx = middleIndex;
}
if (lowerIx + 1 == upperIx) break;
}
if(history[upperIx].Date > date) throw new Exception();
return history[upperIx];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
421 次 |
| 最近记录: |