2010-02-20 13 views
5

के साथ संग्रह में आइटम ढूंढें यदि मेरे पास तिथियों और मूल्यों का संग्रह है।निकटतम दिनांक

  1. एसोसिएटेड संग्रह में अब तक का
  2. अगर यह मौजूद नहीं है, मैं दो अंक उस बिंदु मैं देख रहा हूँ के आसपास रहे हैं के बीच एक रैखिक प्रक्षेप हैं: मैं मान जो या तो प्राप्त करना चाहते हैं

एओ, यहां एक साधारण उदाहरण है। यदि संग्रह है: अगर एक अन्य (शब्दकोश, सरणी, आदि से हल करने में बेहतर है

Date Value 
1/1/2009 100 
1/1/2010 200 
1/1/2011 300 

अगर मैं 2010/06/01 रहा हूँ मैं वापस 250. एक मूल्य मिलेगा मैं किसी भी संग्रह का उपयोग कर सकते ..)

उत्तर

2

एक साधारण क्रमबद्ध (तिथि) सूची पर्याप्त होगी। बस अंतिम तिथि ढूंढें (चलिए इसे d1 पर कॉल करें) जो उस तारीख से कम या बराबर है जिसे आप ढूंढ रहे हैं (चलिए इसे एक डी पर कॉल करें)। अगली तारीख डी 2 तब डी होगी, मान लीजिए कि कोई डुप्लिकेट तिथियां नहीं हैं।

अब अगर मूल्य v1d1 और v2 से मेल खाती है d2 से मेल खाती है तो मूल्य आप देख रहे हैं v1 + (v2 - v1) है/(d2 - डी 1) * (डी - डी 1)।

+0

मैं देखना चाहता था कि रैखिक खोज – leora

+0

के अलावा इसे करने का कोई तेज़ तरीका है या नहीं, जैसा कि यहां कोई व्यक्ति पहले से ही उल्लेख करता है: यदि आपकी सूची सॉर्ट की गई है तो आप बाइनरी खोज कर सकते हैं। –

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) 
     ... 
    } 
} 
+0

@Vlad - यहां कंटेनर और सुई क्या है? – leora

+0

'सुई' एक 'डेटटाइम' है जिसे आप – Vlad

+0

'कंटेनर' के लिए खोज रहे हैं, गलत था, वास्तव में इसे 'हैस्टैक' – Vlad

7

आप जोड़े को पकड़ने के लिए सूची प्रकार का उपयोग कर सकते हैं, उन्हें सॉर्ट करें और 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; 

बेशक कोड सर्वोत्तम संभव नहीं है, लेकिन आप अंदाजा हो:

उदाहरण के लिए आप निम्नलिखित की तरह कुछ हो सकता था सूची का उपयोग करें, क्रमबद्ध यह और फिर BinarySearch है।

अधिक जानकारी के लिए एमएसडीएन लुकअप।

सूची: 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

+0

यह बाइनरीशर्च में एक उत्साही अंतर्दृष्टि है। धन्यवाद। – Echilon

2

एक "तिथियों की सूची" और एक "संदर्भ तिथि" को देखते हुए, हो जाता है "निकटतम n संख्या" । सी # कोड परीक्षण किया।

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); 
    } 
} 
+0

अभी संपादित किया गया। एल्गोरिदम परीक्षण किया। –

+0

काम करता है, लेकिन प्रदर्शन ओ (एन) –

+0

@TheodoreZographos क्या यह एक विनिर्देश/आवश्यकता थी? अगर यह काम करता है; यह काम करता हैं –

संबंधित मुद्दे