2012-11-14 19 views
9

का उपयोग कर सॉर्टिंग सेट्स मैं जानना चाहता हूं कि हम पूर्व निर्मित सेट को सॉर्ट कर सकते हैं या नहीं। जब मैं पहली बार सेट s_p2 बनाता हूं, तो मैं एक अलग तत्व बिंदु का उपयोग कर क्रमबद्ध करता हूं .getLength()। लेकिन उपयोगकर्ता इनपुट के बाद मैं आइटम्स को x value point.getX() के अनुसार क्रमबद्ध करना चाहता हूं। मैं यह कैसे करता हूँ?std :: sort

ऐसा लगता है कि सेट कंटेनर में कोई सॉर्ट फ़ंक्शन नहीं है। और मुझे वेक्टर का उपयोग करने की सलाह दी गई है। लेकिन सेट केवल अद्वितीय तत्वों को स्टोर करने में सक्षम हैं।

Q1: मैं कैसे मापदंड के आधार पर

Q2 एक सेट सॉर्ट कर सकते हैं: अगर सेट इस जो की तुलना में एसटीएल कंटेनर सबसे अच्छा विकल्प है करने में असमर्थ है और मैं कैसे कंटेनर में तत्व सॉर्ट कर सकते हैं।

उत्तर

11

करने के लिए एक 2 टेम्पलेट पैरामीटर आपूर्ति कर सकते हैं आप एक set सहारा नहीं कर सकते हैं, यह कैसे सॉर्ट करता विशेष set के प्रकार का हिस्सा है। दिए गए set में एक निश्चित सेट ऑर्डर है जिसे बदला नहीं जा सकता है।

आप एक ही डेटा के साथ अपेक्षाकृत आसानी से set बना सकते हैं। नए मानदंडों के आधार पर बस एक नया set बनाएं।

यदि आप एक ही कोड में दो set एस का उपयोग करना चाहते हैं, तो आपको अंतर्निहित set पर पहुंच को सारणी करना होगा।

अब, यदि आप दुर्लभ पठन और संशोधन कर रहे हैं, तो vector का उपयोग करके आप मैन्युअल रूप से सॉर्ट करते हैं। आप std::unique - erase idiom का उपयोग करके डुप्लीकेट हटा सकते हैं।

+0

वेक्टर मेरे साथ ठीक है। लेकिन मुझे यकीन नहीं है कि std :: अद्वितीय-मिटाएं कैसे कार्यान्वित करें। क्या आप सलाह दे सकते हैं? –

+2

@ user1571494: एक सॉर्ट किए गए वेक्टर को देखते हुए, 'v.erase (std :: अद्वितीय (v.begin(), v.end()), v.end());' डुप्लिकेट हटा देगा। –

+3

ध्यान दें कि उपरोक्त कोड @ माइक ने लिखा है कि उनकी तुलना करने के लिए 'ऑपरेटर ==' का उपयोग किया जाएगा। आपको भविष्यवाणी करने की आवश्यकता हो सकती है ताकि आप केवल उन चीजों को नकार सकें जो क्रमबद्ध समकक्ष हैं (! (A Yakk

7

std::set अपने सदस्यों को एक क्रमबद्ध फैशन में संग्रहीत करता है। यदि आप .begin() से .end() पर सेट के माध्यम से चलते हैं, तो आपके पास आइटमों की एक क्रमबद्ध सूची होगी।

आप डिफ़ॉल्ट सॉर्ट मापदंड पसंद नहीं है, तो आप std::set<>

+0

हाँ .. मैं समझता हूँ। लेकिन क्या मैं इसे –

+0

@ user1571494 पुन: क्रमबद्ध कर सकता हूं - नहीं, आप इसे फिर से क्रमबद्ध नहीं कर सकते। आप * std :: set <> 'और आइटम को एक अलग कंटेनर में कॉपी कर सकते हैं - शायद एक अलग तुलना टेम्पलेट पैरामीटर के साथ' std :: set'। –

+0

मेरा मानना ​​है कि सेट एक तुलनित्र, या एक ऑब्जेक्ट (या तो एक फ़ंक्शन के लिए पॉइंटर या फ़ंक्शन कॉल ऑपरेटर वाला क्लास) स्वीकार करते हैं जो सेट में 2 ऑब्जेक्ट्स लेने और उनके बीच एक पूर्ण क्रम निर्धारित करने में सक्षम है। यदि आप इस पृष्ठ के निचले भाग पर उदाहरण देखते हैं: http://www.cplusplus.com/reference/stl/set/set/, एक कस्टम तुलनित्र के साथ एक सेट का एक उदाहरण है। – Wug

3

आपके पास दो सेट हो सकते हैं और उन्हें सिंक में रख सकते हैं या एक दूसरे को कॉपी कर सकते हैं।

#include <iostream> 
#include <set> 

using namespace std; 

struct AB 
{ 
    AB(int a,int b) : _a(a),_b(b) {} 

    int _a; 
    int _b; 
}; 

struct byA 
{ 
    bool operator() (const AB& lhs, const AB& rhs) 
    { 
      return lhs._a <= rhs._a; 
    } 
}; 

struct byB 
{ 
    bool operator() (const AB& lhs, const AB& rhs) 
    { 
     return lhs._b <= rhs._b; 
    } 
}; 

typedef set<AB,byA> ByA; 
typedef set<AB,byB> ByB; 
typedef ByA::const_iterator ByAIt; 
typedef ByB::const_iterator ByBIt; 

void getByB(const ByA &sA,ByB &sB) 
{ 
    for(ByAIt iter=sA.begin(); iter!=sA.end();++iter) { 
     const AB &ab=*iter; 
     sB.insert(ab); 
    } 
} 

int main(int argc, const char **argv) 
{ 
    ByA sA; 
    sA.insert(AB(3,6)); 
    sA.insert(AB(1,8)); 
    sA.insert(AB(2,7)); 

    ByB sB; 
    getByB(sA,sB); 

    cout << "ByA:" << endl; 
    for(ByAIt iter=sA.begin(); iter!=sA.end();++iter) { 
     const AB &ab=*iter; 
     cout << ab._a << "," << ab._b << " "; 
    } 
    cout << endl << endl; 

    cout << "ByB:" << endl; 
    for(ByBIt iter=sB.begin(); iter!=sB.end();++iter) { 
     const AB &ab=*iter; 
     cout << ab._a << "," << ab._b << " "; 
    } 
    cout << endl; 
    return 0; 
} 

कार्यक्रम रिटर्न: Bya 1,8 2,7 3,6

BYB: 3,6 2,7 1,8