如果我有日期和值的集合。我想這是任何值:在最近日期收集中查找項目
- 關聯到集合中的日期
- 如果不存在的話,我想兩點都是圍繞我找點之間的線性插值
ao,這裏是一個簡單的例子。如果集合是:
Date Value
1/1/2009 100
1/1/2010 200
1/1/2011 300
如果我找2010/6/1我會得到一個值回250,我可以使用任何集合如果一個比另一個(字典,陣列等解決好..)
如果我有日期和值的集合。我想這是任何值:在最近日期收集中查找項目
ao,這裏是一個簡單的例子。如果集合是:
Date Value
1/1/2009 100
1/1/2010 200
1/1/2011 300
如果我找2010/6/1我會得到一個值回250,我可以使用任何集合如果一個比另一個(字典,陣列等解決好..)
一個簡單的排序(在日期)列表就足夠了。只需找到最近的日期(我們稱之爲d1),該日期小於或等於您正在查找的日期(我們稱之爲d)。假設沒有重複的日期,下一個日期d2將通過d。
現在,如果值V1對應D1和V2對應D2那麼你正在尋找的價值V1 +(V2 - V1)/(D2 - d1)*(d-d1)。
你可以試試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)
...
}
}
您可以使用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;
當然的代碼可能不是最好的,但你的想法:用列表,排序,然後做二分查找。
查找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
這是對BinarySearch的深入瞭解。謝謝。 – Echilon 2011-10-09 14:44:18
給出一個 「日期列表」 和 「基準日」,獲得了 「最接近的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);
}
}
剛剛編輯。算法測試。 – 2013-02-02 20:20:01
作品,但表現是O(N) – 2013-04-02 15:56:24
@TheodoreZographos是一個規格/要求?如果它有效;有用 – 2013-04-24 10:15:38
我想看看除了線性搜索之外是否有更快的方法來做 – leora 2010-02-21 22:59:55
還有,這裏有人提到過:如果你的列表已經排序,你可以進行二分搜索。 – 2010-02-22 07:22:54