2013-08-22 6 views
6

मेरे सी ++ प्रोग्राम में मैं अपने मानचित्र को कुंजी के बजाय मूल्य से सॉर्ट करने का प्रयास कर रहा हूं।std :: set घोषित करते समय मुझे सॉर्टिंग सबराउटिन को दोहराने की आवश्यकता क्यों है?

this question से, ऐसा लगता है कि ऐसा करने का तरीका एक सेट बनाना है जिसका तत्व जोड़े हैं और जो मेरे कम से कम कार्य से क्रमबद्ध हैं।

जोड़ने के लिए के बारे में:: एक: 1
तत्व ठीक
सेट है जोड़ा

#include <map> 
#include <set> 
#include <iostream> 
#include <string> 

using namespace std; 

bool compareCounts(const pair<string, size_t> &lhs, const pair<string, size_t> &rhs); 

int main (int argc, char *argv[]) { 
     map <string, size_t> counter = { {"A", 1}, {"B", 2}, {"C", 3} }; 
     set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 
     for (map<string, size_t>::iterator it = counter.begin(); it != counter.end(); ++it) { 
       cout << "About to add: " << it->first << ":" << it->second << endl; 
       auto ret = sorted_counter.insert(*it); 
       if (! ret.second) { 
         cout << "ERROR adding this element!" << endl; 
       } else { 
         cout << "Element added ok" << endl; 
       } 
       cout << "Set is of size: " << sorted_counter.size() << endl; 
     } 

     return 0; 
} 

bool compareCounts(const pair<string, size_t> &lhs, const pair<string, size_t> &rhs) { 
     return lhs.second > rhs.second; 
} 

यहाँ आउटपुट है:

यहां कुछ नमूना कोड जहां मैं यह करने की कोशिश करते हैं है आकार: 1
जोड़ने के बारे में: बी: 2
सेगमेंटेशन गलती: 11

मैंने देखा कि जब मैं दूसरा तत्व जोड़ने के लिए जाता हूं तो चीजें क्रैश हो जाती हैं। मैंने पाया कि यह हो रहा है क्योंकि अब मेरे सॉर्टिंग सबराउटिन, compareCounts पर कॉल करना आवश्यक है।

set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 
इस के लिए

:

ठीक इस लाइन को बदलने के लिए था

set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts); 

क्यों मैं दो बार छँटाई सबरूटीन compareCounts निर्दिष्ट करने के लिए की जरूरत है? क्या संकलक पहले से ही मेरी टाइप परिभाषा से नहीं जानता है?

+0

क्या आप उपयोग कर रहे, 'map' या' set' के बजाय एक functor इस्तेमाल करना चाहिए? यह बल्कि भ्रमित है। कृपया एक स्व-निहित उदाहरण दें – TemplateRex

+0

मैं मूल्यों के आधार पर मानचित्रों को क्रमबद्ध करने के लिए सेट का उपयोग कर रहा हूं। – EMiller

+0

क्या यह एक मांग की बात है या दोनों संरचनाओं की निरंतर जोड़ी है (जिसे मैं दृढ़ता से सलाह देता हूं)? यदि मांग पर है, तो क्या आपने बस अपने स्वयं के तुलनित्र के साथ 'std :: ref >' को वेक्टर में फेंक दिया है और 'std :: sort()' को फायरिंग माना है? – WhozCraig

उत्तर

6
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 

आप निर्दिष्ट कभी नहीं क्या तुलनित्र set वास्तव में उपयोग करना चाहिए। तुलनित्र निर्दिष्ट किया जा रहा बिना

set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts); 

के ऊपर लाइन बदलें, set डिफ़ॉल्ट अपने कोड दुर्घटनाओं का निर्माण एक (nullptr) और जब यह दूसरा तत्व डालने के लिए तुलनित्र उपयोग करने के लिए कोशिश करता है,।

तुम सिर्फ एक समारोह सूचक

struct compareCounts 
{ 
    bool operator()(const pair<string, size_t> &lhs, 
        const pair<string, size_t> &rhs) const 
    { 
     return lhs.second > rhs.second; 
    } 
}; 

set <pair<string, size_t>, compareCounts> sorted_counter; 
+0

आह! और मुझे अभी एहसास हुआ कि यह मेरा सवाल था! – EMiller

+2

@ उपयोगकर्ता 7391 आईई। आपने इसे तुलनित्र के * प्रकार * को बताया, लेकिन वास्तव में कभी नहीं दिया * इसे * दिया। – WhozCraig

+0

@ उपयोगकर्ता 7391 प्रेटोरियन में अतिरिक्त नमूना, इसे टाइप करके (एक मज़ेदार) यह कहकर (और करता है) उस ऑपरेटर() 'के माध्यम से eval के लिए उस प्रकार का एक उदाहरण उपयोग कर सकता है। यह आमतौर पर प्रदर्शन के लिए भी पसंद किया जाता है क्योंकि यह * अत्यधिक * इनलाइन होने की संभावना है। क्या मैं आप थे, मैं उनके मज़ेदार उदाहरण का उपयोग करूंगा। – WhozCraig

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