2011-02-08 7 views
10

की सूची BinarySearch के इस अधिभार साथ शुरू करते हैं:सूची के लिए BinarySearch का उपयोग कैसे करें <T>

public int BinarySearch(T item, IComparer<T> comparer); 

यह सर्वविदित है कि सूची BinarySearch उपयोग करने से पहले उचित IComparer साथ हल कर दिया जाना चाहिए। लेकिन फिर: सूची को खोजने के लिए आपको एक टी आइटम प्रदान करना होगा। यह अपेक्षाकृत अप्रत्याशित है जब किसी को इन वस्तुओं के गुणों (यानी लिंक या प्रतिनिधियों/भविष्यवाणियों का उपयोग करके) सूची में वस्तुओं को खोजने के लिए उपयोग किया जाता है। क्योंकि जब मेरे पास पहले से ही मेरा टी आइटम है तो मुझे इसे खोजना नहीं है!

अब मैं सी #+ कोड को सी # में कार्यान्वित कर रहा था और देखा कि सी ++ प्रोग्रामर ने सी ++ स्टाइल बाइनरी का इस्तेमाल अपने कोड में हर जगह किया है। सबसे पहले उसने एक नया टी आइटम बनाया और इस टी आइटम को वह गुण दिया जो वह ढूंढ रहा था। फिर उन्होंने को उसी गुण के साथ सूची में किसी आइटम की अनुक्रमणिका खोजने के लिए, इसके साथ सूची की खोज की। पाठ्यक्रम की सी ++ तुलनाकर्ता इन गुणों के लिए अनुकूलित किया गया था।

तो यह सूची में आइटम देखने के लिए एक अलग तरीका है। बाइनरीशर्च डमी टी आइटम और एक इंडेक्स की खोज करता है जिसके साथ यह सूची में वास्तविक टी आइटम पुनर्प्राप्त कर सकता है। एक लिंक बिंदु से यह अप्राकृतिक लगता है।

मेरे प्रश्न हैं:

मैं BinarySearch के पीछे विचार का सही विवरण दिया है?

क्या आपको लगता है कि एक डमी टी आइटम पहले बिना बाइनरीशर्च के साथ लिंक शैली खोज का उपयोग करना संभव है?

उत्तर

5

Did I give a correct description of the idea behind BinarySearch?
हां।

Do you think it is possible to use a Linq style search with BinarySearch without making a dummy T item first?
इसके वर्तमान स्वरूप में नहीं है। आप एक रैपर का उपयोग कर सकते हैं जो आपके लिए डमी टी बनाएगा, यह केवल विशिष्ट त्स के लिए काम करेगा, हालांकि (पैरामीटर रहित कन्स्ट्रक्टर आदि के साथ)।

+0

यह केवल विशिष्ट टी के लिए क्यों काम करेगा, उस पर कोई दस्तावेज? – Gerard

+0

आप (व्यावहारिक रूप से) सभी संस्थाओं के लिए एक सार्वभौमिक निर्माण विधि नहीं कर सकते हैं। आपके पास विभिन्न प्रकार के कन्स्ट्रक्टर पैरामीटर वाले वर्ग हैं - आप स्वचालित रूप से कौन सा चयन करेंगे? आप पैरामीटर स्वचालित रूप से कैसे आपूर्ति करेंगे? यह structs और पैरामीटर रहित वर्गों के लिए आसान होगा, जिन्हें आप प्रतिबंधित कर सकते हैं। उस संबंध में यह (आईएमएचओ) एक डमी टी बनाने के लिए आसान तरीका है - क्योंकि टी कुछ भी हो सकता है। –

+0

शायद यह सामान्य वाक्यविन्यास 'जहां टी: बेसटाइप' का उपयोग करने में मदद करता है और रैपर बेसटाइप के कन्स्ट्रक्टर का उपयोग कर सकता है? – Gerard

0

दरअसल, LINQ में कुछ भी समान नहीं है, लेकिन आप अपने स्वयं के एक्सटेंशन बना सकते हैं। यह उदाहरण आपको नहीं एक डमी आइटम पारित करने के लिए अनुमति देते हैं, लेकिन उदाहरण के लिए सिर्फ मूल comparer में इस्तेमाल किया संपत्ति:

public static int FindFirstIndexGreaterThanOrEqualTo<TElement, TKey>(
       this IList<TElement> keySortedCollection, 
       TKey key, 
       Func<TElement, TKey> keySelector, 
       IComparer<TKey> keyComparer) 
{ 
    int begin = 0; 
    int end = keySortedCollection.Count; 
    while (end > begin) 
    { 
     int index = (begin + end)/2; 
     TElement el = keySortedCollection[index]; 
     TKey currElKey = keySelector(el); 
     if (keyComparer.Compare(currElKey, key) >= 0) 
      end = index; 
     else 
      begin = index + 1; 
    } 
    return end; 
} 

public static int FindFirstIndexGreaterThanOrEqualTo<TElement, TKey>(
       this IList<TElement> keySortedCollection, 
       TKey key, 
       Func<TElement, TKey> keySelector) 
{ 
    return FindFirstIndexGreaterThanOrEqualTo(keySortedCollection, 
               key, 
               keySelector, 
               Comparer<TKey>.Default); 
} 
इन तरीकों के साथ

, आप एक तुलना एक के एक सबसेट आप मूल रूप से प्रयोग किया जाता है कि दे सकता है संग्रह को सॉर्ट करने के लिए।

जाहिर है, जब आप मूल तुलनाकर्ता के उप-समूह का उपयोग कर रहे हैं, तो आप एक एकल अनुक्रमणिका नहीं ढूंढ सकते हैं। तो ये विधियां बाइनरी खोज के निचले स्तर पर लौटती हैं।

+0

लिटिल स्पष्टीकरण जोड़ा गया। (अन्यथा यह ऑफ-विषय प्रतीत होता है ...) – digEmAll

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