2010-10-30 33 views
5

निम्न कोड की जाँच करें:का प्रयोग तुलनित्र सेट

string toLowerCase(const string& str) { 
    string res(str); 
    int i; 

    for (i = 0; i < (int) res.size(); i++) 
     res[i] = (char) tolower(res[i]); 

    return res; 
} 

class LeagueComparator 
{ 
public: 
    bool operator()(const string& s1, const string& s2) 
    { 
     return toLowerCase(s1) < toLowerCase(s2); 
    } 
}; 

int main() 
{ 
    set<string, LeagueComparator> leagues; 
    set<string, LeagueComparator>::iterator iter; 

    leagues.insert("BLeague"); 
    leagues.insert("aLeague"); // leagues = {"aLeague", "BLeague"} 
    leagues.insert("ALeague"); 

    for (iter = leagues.begin(); iter != leagues.end(); iter++) 
     cout << *iter << endl; 

    return 0; 
} 

उत्पादन होता है:

aLeague 
BLeague 

जो मेरे लिए चौंकाने वाला है। मैंने सोचा था कि (और उम्मीद) उत्पादन होगा:

aLeague 
ALeague 
BLeague 

leagues.insert("ALeague"); के निष्पादन से पहले, leagues"aLeague" और "BLeague" शामिल हैं। मेरा सवाल है, leagues.insert("ALeague"); निष्पादित करते समय मशीन "ALeague" == "aleague" का इलाज क्यों करती है? मेरी समझ के अनुसार, leagues में कोई तत्व "ALeague" नहीं है। तो "ALeague"leagues में डाला जाना चाहिए। तुलनित्र को निर्धारित करना चाहिए कि "ALeague" कहां रखा जाए।

अग्रिम धन्यवाद।

पीएस: कृपया मुझे सी शैली कास्ट का उपयोग करने के लिए मत मारो। : पी static_cast टाइप करने के लिए मैं बहुत आलसी हूं।

+0

तथ्य यह महसूस करता है कि आप एक C++ शैली डाली मुख्य कारण C++ शैली डाले में से एक है प्रदर्शन करने के लिए काम करना है मौजूद - अर्थात् है कि आप कास्टिंग के किसी भी प्रकार से बचना चाहिए सी ++ में। इस मामले में आपको पूरी तरह से कास्ट को हटा देना चाहिए, और इसके बजाय सही प्रकारों का उपयोग करना चाहिए। अर्थात। '(int) res.size()' के बजाय, कास्ट हटाएं और 'i' के प्रकार को 'हस्ताक्षरित' के रूप में बदलें। –

+0

इसके अलावा, 'i' को लूप में घोषित किया जाना चाहिए, लूप के बाहर नहीं। और सी ++ में, toLowerCase शायद एक स्पष्ट लूप लिखने के बजाय 'std :: transform (str.begin(), str.end(), str.begin(), std :: ptr_fun (tolower)) को कॉल करना चाहिए। –

+0

@ बिली ओनेल: धन्यवाद।मुझे 'ट्रांसफॉर्म() 'का उपयोग करने के लिए इस्तेमाल करने की आवश्यकता है। कि 'toLowerCase' कई साल पहले मेरे द्वारा लिखा गया था। मुझे लगता है कि उस समय मुझे 'ट्रांसफॉर्म' के बारे में पता नहीं था। मैं अपना कोडबेस अपडेट करूंगा। – Donotalo

उत्तर

14

के लिए आपका तुलनित्र, "aLeague" == "ALeague" कहता है। चूंकि (आपके तुलनित्र के अनुसार) "aLeague" < "ALeague" == false और "ALeague" < "aLeague" == false, वे समकक्ष होना चाहिए। और एक सेट में समकक्ष तत्व डालने से कुछ भी नहीं होता है।

+3

+1। ध्यान दें कि तुलनित्र समानता स्थापित नहीं कर रहा है, यह समानता स्थापित कर रहा है। एक अंतर है w.r.t. मानक और एसटीएल दस्तावेज। –

+0

धन्यवाद, मेरी पोस्ट संपादित करें। –

3

आपके द्वारा प्रदान किए गए तुलनित्र को देखते हुए, "एलीग" वास्तव में समकक्ष "एलेग" है।

दो मानों, x और y, और एक कम से तुलनित्र जेड को देखते हुए:

  • तो जेड (एक्स, वाई) सच है, फिर एक्स वाई से भी कम है
  • तो जेड (y, एक्स) सच है, तो y x
  • से कम है यदि न तो सत्य है, तो एक्स y
  • के बराबर है यदि दोनों सत्य हैं, तो आपके पास टूटा तुलनित्र है।
+0

+1, लेकिन तीसरी बुलेट w.r.t. के साथ मामूली समस्या एसटीएल दस्तावेज़ समानता और समानता के बीच एक अंतर है। तुलनित्र से कम समानता स्थापित नहीं कर सकता, केवल समानता। –

+0

@ बिली ओनेल: एसटीएल डॉक्टर के अनुसार (मेरे पास यह नहीं है), 'समानता' और 'समकक्षता' की परिभाषाएं क्या हैं? – Donotalo

+0

@ डोनोटलो: समानता तुलना समानता तुलनाकर्ता, या 'ऑपरेटर == 'का उपयोग करके तुलना की जाती है। समानता वह राज्य है जहां तर्ककर्ता या 'ऑपरेटर <' से कम तर्क के आदेश के लिए झूठा रिटर्न देता है, जैसा कि यहां निर्दिष्ट है। संकल्पनात्मक रूप से, यह [समानता तुलनीय] (http://www.sgi.com/tech/stl/EqualityComparable.html) और [तुलनात्मक से कम] के बीच अंतर है (http://www.sgi.com/tech/stl/ LessThanComparable.html)। –

4

जब आप किसी सेट में कोई मान डालते हैं, तो ऑब्जेक्ट यह देखने के लिए जांच करता है कि इसमें पहले से ही वह मान है या नहीं। आपकी LeagueComparator ऑब्जेक्ट ALeague की तुलना में पहले से ही सेट में मौजूद दो अन्य मानों के साथ तुलना करता है। यह निर्धारित करता है कि मौजूदा मान aLeague प्रस्तावित नई प्रविष्टि (ALeague) से अधिक न तो उससे अधिक है, इसलिए वे बराबर होना चाहिए, और इसलिए यह सम्मिलन के साथ आगे नहीं बढ़ता है। सेट केवल दो तत्वों के साथ रहता है। ग्राहक तुलना ऑब्जेक्ट प्रदान करने का यह पूरा बिंदु है, ताकि आप यह निर्धारित कर सकें कि सेट कैसे निर्धारित करता है कि दो तत्व मेल खाते हैं या नहीं।

+0

+1। ध्यान दें कि एसटीएल दस्तावेज़ों के अनुरूप होने के लिए, यहां "बराबर" के अधिकांश उपयोगों को "समतुल्य" के साथ प्रतिस्थापित किया जाना चाहिए। तुलनात्मक से कम समानता स्थापित नहीं कर सकते हैं। –

0

बदलें अपनी LeagueComparator

साथ
class LeagueComparator 
{ 
public: 
    bool operator()(const string& s1, const string& s2) 
    { 
     return toLowerCase(s1) < toLowerCase(s2) || 
       !(toLowerCase(s2) < toLowerCase(s1)) && s1 < s2; 
    } 
}; 
+0

यह कोई तुलनात्मक निर्दिष्ट करने के बराबर है। आपका तुलनित्र बस सभी मामलों में 's1

+0

यह सच नहीं है। 's1 =" बी "', 's2 =" ए "'। मेरा तुलनित्र 'झूठी || के कारण' झूठा 'देता है सत्य और सही = झूठा'। 's1

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