2009-06-21 14 views
5

के लिए comparer उपयोग करने के लिए एक और सवाल मैं यहाँ से पूछा मैं अपने वस्तुओंकैसे एक HashSet

के लिए एक HashSet उपयोग करने के लिए मैं एक स्ट्रिंग और अपने मालिक के लिए एक संदर्भ युक्त वस्तुओं का निर्माण करेगा चाहते हैं के परिणामस्वरूप।

public class Synonym 
{ 
    private string name; 
    private Stock owner; 
    public Stock(string NameSynonym, Stock stock) 
    { 
     name=NameSynonym; 
     owner=stock 
    } 
    // [+ 'get' for 'name' and 'owner'] 
} 

मुझे समझ में आता है कि मुझे तुलनात्मक की आवश्यकता है, लेकिन पहले कभी इसका उपयोग नहीं किया गया था। क्या मुझे एक अलग वर्ग बनाना चाहिए? जैसे:

public class SynonymComparer : IComparer<Synonym> 
{ 
    public int Compare(Synonym One, Synonym Two) 
    { // Should I test if 'One == null' or 'Two == null' ???? 
     return String.Compare(One.Name, Two.Name, true); // Caseinsesitive 
    } 

}

मैं एक समारोह (या नेस्टेड वर्ग [? शायद एक सिंगलटन] यदि आवश्यक हो) वर्ग पर्याय के बजाय एक और (स्वतंत्र) वर्ग का हिस्सा होने के लिए पसंद करते हैं। क्या यह संभव है?

उपयोग के बारे में: जैसा कि मुझे लगता है कि मुझे क्लास समानार्थी के अंदर एक खोज (स्ट्रिंग नेमसिंकीम) फ़ंक्शन लिखना चाहिए, लेकिन मुझे यह कैसे करना चाहिए?

public class SynonymManager 
{ 
    private HashSet<SynonymComparer<Synonym>> ListOfSynonyms; 

    public SynonymManager() 
    { 
     ListOfSymnonyms = new HashSet<SynonymComparer<Synonym>>(); 
    } 

    public void SomeFunction() 
    { // Just a function to add 2 sysnonyms to 1 stock 
     Stock stock = GetStock("General Motors"); 
     Synonym otherName = new Synonym("GM", stock); 
     ListOfSynonyms.Add(otherName); 
     Synonym otherName = new Synonym("Gen. Motors", stock); 
     ListOfSynonyms.Add(otherName); 
    } 

    public Synonym Find(string NameSynomym) 
    { 
     return ListOfSynonyms.??????(NameSynonym); 
    } 
} 

उपरोक्त कोड में मुझे नहीं पता कि 'ढूंढें' विधि को कैसे कार्यान्वित किया जाए। मैं कैसे करूं?

किसी भी मदद की सराहना की होगी (पी एस यह कैसे लागू किया जाना चाहिए के बारे में मेरे विचारों को पूरी तरह से गलत मुझे पता है और मुझे बताओ कि लागू करने के लिए कर रहे हैं)

+0

क्या मैं अपना उत्तर सुधारने के लिए कुछ और कर सकता हूं? –

उत्तर

13

एक HashSet एक IComparer<T> की जरूरत नहीं है - यह एक IEqualityComparer<T> की जरूरत है, इस तरह के रूप

public class SynonymComparer : IEqualityComparer<Synonym>  
{ 
    public bool Equals(Synonym one, Synonym two) 
    { 
     // Adjust according to requirements. 
     return StringComparer.InvariantCultureIgnoreCase 
          .Equals(one.Name, two.Name); 

    } 

    public int GetHashCode(Synonym item) 
    { 
     return StringComparer.InvariantCultureIgnoreCase 
          .GetHashCode(item.Name); 

    } 
} 

हालांकि, अपने वर्तमान कोड केवल संकलित क्योंकि आप बल्कि का एक सेट से comparers का एक सेट बना रहे हैं समानार्थी शब्द

इसके अलावा, मुझे नहीं लगता कि आप वास्तव में एक सेट चाहते हैं।मुझे ऐसा लगता है कि आप एक शब्दकोश या एक देखने ताकि आप किसी दिए गए नाम के लिए समानार्थी शब्द पा सकते हैं:

public class SynonymManager 
{ 
    private readonly IDictionary<string, Synonym> synonyms = new 
     Dictionary<string, Synonym>(); 

    private void Add(Synonym synonym) 
    { 
     // This will overwrite any existing synonym with the same name. 
     synonyms[synonym.Name] = synonym; 
    } 

    public void SomeFunction() 
    { 
     // Just a function to add 2 synonyms to 1 stock. 
     Stock stock = GetStock("General Motors"); 
     Synonym otherName = new Synonym("GM", stock); 
     Add(otherName); 
     ListOfSynonyms.Add(otherName); 
     otherName = new Synonym("Gen. Motors", stock); 
     Add(otherName); 
    } 

    public Synonym Find(string nameSynonym) 
    { 
     // This will throw an exception if you don't have 
     // a synonym of the right name. Do you want that? 
     return synonyms[nameSynonym]; 
    } 
} 

नोट वहाँ के बारे में, इसके बाद के संस्करण कोड में कुछ सवाल हैं कि आप कैसे यह व्यवहार करना चाहते हैं विभिन्न मामलों आपको बिल्कुल पर काम करने की आवश्यकता है जो आप करना चाहते हैं।

संपादित करें: आप एक ही पर्याय के लिए कई शेयरों स्टोर करने के लिए सक्षम होना चाहते हैं, तो आप को प्रभावी ढंग से चाहते एक Lookup<string, Stock> - लेकिन यह है कि अपरिवर्तनीय है। आप शायद Dictionary<string, List<Stock>> संग्रहित कर रहे हैं; प्रत्येक स्ट्रिंग के लिए स्टॉक की एक सूची।

Find से एक त्रुटि फेंक नहीं के संदर्भ में, आप Dictionary.TryGetValue पर गौर करना चाहिए जो करता है, तो कुंजी नहीं मिला है एक अपवाद फेंक नहीं है (और यह भी है या नहीं, कुंजी था पाया रिटर्न); मैप किए गए मान को आउट पैरामीटर में "वापस" किया जाता है।

+0

मान लीजिए कि उसे केवल एक शब्दकोश की आवश्यकता है, (मेरा जवाब उन पंक्तियों के साथ भी जाता है), मुझे आश्चर्य है कि शब्दकोश कैसे कार्यान्वित किया जाता है। क्या हैश डिक्शनरी जैसी कोई चीज है (जो आंतरिक रूप से कुंजी पकड़ने के लिए हैशसेट का उपयोग करती है और फिर लुकअप के लिए मानक शब्दकोश)? –

+0

शुरुआत में मैं एक स्टॉक वाला नाम परिभाषित करता हूं (जो उस विशेष स्टॉक के लिए पहला पर्याय होगा)।फिर यह संभव होगा कि उपयोगकर्ता किसी विशेष स्टॉक के लिए अपना समानार्थी नाम प्रदान करेगा (शब्दकोश में जोड़ा जाएगा), लेकिन फ़ाइल को पढ़ने के दौरान यह समानार्थी (या कई) भी मिल सकता है (यानी एक सुरक्षा द्वारा परिभाषित किया गया है इसकी आईएसआईएन लेकिन [लगभग] प्रत्येक साइट स्टॉक के मूल्य दिखाती है, इसके लिए एक अलग नाम का उपयोग किया जाएगा, इसलिए उन सभी अलग-अलग नामों को एक ही सुरक्षा (= आईएसआईएन) से जोड़ा जाना चाहिए। मैं खोज में अपवाद नहीं फेंकना चाहता हूं लेकिन यह जानने की आवश्यकता है कि एक समानार्थी मौजूद है या उसका स्टॉक – SoftwareTester

+2

@ilya: शब्दकोश <,> हमेशा हैशटेबल दृष्टिकोण का उपयोग करता है - लेकिन यह आंतरिक रूप से हैशसेट का उपयोग नहीं करता है। असल में दोनों प्रकार एक ही अवधारणा (हैशिंग) का उपयोग कर रहे हैं लेकिन वे अलग-अलग प्रदान कर रहे हैं इंटरफेस - एक सेट में केवल यह अवधारणा है कि कोई आइटम सेट में है या नहीं, जबकि एक शब्दकोश एक मूल्य के लिए एक कुंजी है। आप आसानी से मूल्य को अनदेखा करके एक शब्दकोश दिया गया हैशसेट को आसानी से कार्यान्वित कर सकते हैं - शब्दकोश बनाना मुश्किल है एक हैश से सेट। –

1

इसे और अधिक उचित होना नहीं चाहेंगे Synonym वर्ग स्क्रैप पूरी तरह से और समानार्थी की सूची Dictonary (या, यदि ऐसी कोई चीज है, HashDictionary) तारों की है?

(मैं सी # प्रकार के साथ बहुत परिचित नहीं हूँ, लेकिन मुझे आशा है कि यह बता देते हैं सामान्य विचार)

जवाब मेरा सुझाव है (संपादित, अब मामले का सम्मान करता है):

IDictionary<string, Stock>> ListOfSynonyms = new Dictionary<string,Stock>>(); 
    IDictionary<string, string>> ListOfSynForms = new Dictionary<string,string>>(); 
    class Stock 
    { 
     ... 
     Stock addSynonym(String syn) 
     { 
      ListOfSynForms[syn.ToUpper()] = syn; 
      return ListOfSynonyms[syn.ToUpper()] = this; 
     } 
     Array findSynonyms() 
     { 
      return ListOfSynonyms.findKeysFromValue(this).map(x => ListOfSynForms[x]); 
     } 
    } 

    ... 
    GetStock("General Motors").addSynonym('GM').addSynonym('Gen. Motors'); 
    ... 
    try 
    { 
     ... ListOfSynonyms[synonym].name ... 
    } 
    catch (OutOfBounds e) 
    { 
     ... 
    } 
    ... 
    // output everything that is synonymous to GM. This is mix of C# and Python 
    ... GetStock('General Motors').findSynonyms() 
    // test if there is a synonym 
    if (input in ListOfSynonyms) 
    { 
     ... 
    } 
+0

मुझे यह पता लगाने में सक्षम होना चाहिए कि स्टॉक प्रत्येक विशेष समानार्थी के साथ क्या जुड़ा हुआ है (cours के इस उदाहरण में जो दिखाया नहीं गया है, लेकिन वास्तव में यह करता है) – SoftwareTester

+0

निश्चित रूप से, इसलिए मैं दोनों उदाहरणों को सूचीOfSynonims शब्दकोश में रखता हूं। Synonim से स्टॉक खोजने के लिए आप "ListOfSynonims [synonim]" लिखते हैं। –

+0

जैसा कि आप देखते हैं, यह वही है जो आप चाहते थे, लेकिन इसके बजाय ????? (synonymim) लिखते हैं [synonim] :) –

0

तुम हमेशा कर सकते हैं LINQ का उपयोग देखने करना है:

public Synonym Find(string NameSynomym) 
{ 
    return ListOfSynonyms.SingleOrDefault(x => x.Name == NameSynomym); 
} 

लेकिन, आप के बजाय एक शब्दकोश का उपयोग कर माना जाता है, मेरा मानना ​​है कि, यह बेहतर ही सदस्यों को निकालने के लिए अनुकूल है और आप अभी भी है कि गारंटी ले सकते हैं वहाँ आपके द्वारा चुने गए कुंजी के आधार पर कोई डुप्लिकेट नहीं है।

मुझे यकीन नहीं है कि लुकअप का समय सिंगलऑर्डफॉल्ट का है, लेकिन मुझे पूरा यकीन है कि यह रैखिक (ओ (एन)) है, इसलिए यदि लुकअप समय आपके लिए महत्वपूर्ण है, तो एक शब्दकोश आपको ओ (1) लुकअप प्रदान करेगा पहर।

+0

सबसे पहले: इसे तुलनात्मक की आवश्यकता नहीं है ??? दूसरा: यह खोज समानार्थी का सदस्य कार्य है। क्या आवश्यक है और उस 'एक्स' के बारे में क्या है? – SoftwareTester

+0

सिंगलऑर्डडिल्ट आईन्यूमेरेबल पर एक विस्तार विधि है, जो हैशसेट लागू करता है। इससे आपको नाम से मेल खाने वाले एकल तत्व को खोजने के लिए सिंगलऑर्डफॉल्ट (या केवल सिंगल) का उपयोग करने की अनुमति मिलती है। आप अपने तुलनाकर्ता के रूप में "x => x.Name == NameSynomym" पर विचार कर सकते हैं। यह केवल आंकड़े बताता है कि यह एक एक्स लेता है (आपके मामले में, यह ListOfSynonyms से समानार्थी है), और यदि x.Name == NameSynomym सत्य है, तो यह आपको वापस एक्स देता है। अगर यह कोई मैच नहीं मिलता है, तो यह शून्य हो जाएगा। –

+0

लेकिन यह निर्दिष्ट स्थिति के साथ एक से अधिक तत्व अगर अपवाद फेंकता है! – nawfal

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