如果我有一组日期和价值观。我希望获得以下值:
ao,这是一个简单的例子。如果集合是:
Date Value
1/1/2009 100
1/1/2010 200
1/1/2011 300
如果我正在寻找6/1/2010,我会得到一个250的值。我可以使用任何集合,如果一个比另一个更好(字典,数组等)。
答案 0 :(得分:7)
您可以使用List类型来保存对,对它们进行排序并使用List.BinarySearch。
例如,您可以使用以下内容:
struct Pair
{
public Pair(DateTime t, int v)
{
date = t;
value = v;
}
public DateTime date;
public int value;
}
....
List<Pair> pairs = new List<Pair>();
pairs.Add(new Pair(DateTime.Now, 100));
pairs.Add(new Pair(DateTime.Now, 200));
....
// Sort using the time.
pairs.Sort(delegate(Pair pair1, Pair pair2) {
return pair1.date.CompareTo( pair2.date);
}
);
// Do binary search.
int index = pairs.BinarySearch(new Pair(dateToSearch, 0),
delegate(Pair pair1, Pair pair2) {
return pair1.date.CompareTo(pair2.date);
});
if (index >= 0) {
// Found the element!
return pairs[index].value;
}
// If not found, List.BinarySearch returns the complement
// of the index where the element should have been.
index = ~index;
// This date search for is larger than any
if (index == pairs.Count) {
//
}
// The date searched is smaller than any in the list.
if (index == 0) {
}
// Otherwise return average of elements at index and index-1.
return (pairs[index-1].value + pairs[index].value)/2;
当然代码不是最好的,但你明白了:使用List,对它进行排序然后再做BinarySearch。
查找MSDN以获取更多信息。
列表:http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
List.Sort:http://msdn.microsoft.com/en-us/library/3da4abas.aspx
List.BinarySearch:http://msdn.microsoft.com/en-us/library/3f90y839.aspx
答案 1 :(得分:2)
简单的排序(日期)列表就足够了。只需找到小于或等于您要查找的日期的最后日期(让我们称之为 d1 )(让我们称之为 d )。假设没有重复日期,下一个日期 d2 将超过 d 。
现在,如果值 v1 对应 d1 且 v2 对应 d2 ,那么您要查找的值是 v1 +( v2 - v1 )/( d2 - d1 )* ( d - d1 )。
答案 2 :(得分:2)
给定“日期列表”和“参考日期”,获取“最接近的n个数字”。 C#代码测试。
public class ClosestDate
{
public void GetClosestDate(DateTime referenceDate,
List<DateTime> listDates, int maxResults)
{
// final ordered date list
List<DateTime> finalList = new List<DateTime>();
DateTime selectedDate = DateTime.MaxValue;
// loop number of results
for (int i = 0; i < maxResults; i++)
{
// get next closest date
int tempDistance = int.MaxValue;
foreach (DateTime currentDate in listDates)
{
int currenDistance = this.DateDiff(currentDate, referenceDate);
if (currenDistance < tempDistance)
{
tempDistance = currenDistance;
selectedDate = currentDate;
}
}
// build final list
finalList.Add(selectedDate);
// remove element from source list
listDates.Remove(selectedDate);
}
// print results
foreach (DateTime date in finalList)
{
Console.WriteLine(date.ToShortDateString());
}
}
private int DateDiff(DateTime Date1, DateTime Date2)
{
TimeSpan time = Date1 - Date2;
return Math.Abs(time.Days);
}
}
答案 3 :(得分:0)
您可以尝试SortedDictionary
。做那样的事情:
int FindInterpolated(DateTime needle)
{
try
{
DateTime lower = haystack.First(key => haystack[key] <= needle);
DateTime upper = haystack.Last(key => haystack[key] >= needle);
int v1 = haystack[lower];
int v2 = haystack[upper];
long ticksLower = lower.Ticks;
long ticksUpper = upper.Ticks;
return (v1 * ticksLower + v2 * ticksUpper) / (ticksLower + ticksUpper);
}
catch (InvalidOperationException)
{
// thrown if needle is out of range
// (not between smallest and biggest keys in the haystack)
...
}
}