2009-03-26 16 views
17

C++ का सबसे अच्छा तरीका वेक्टर के लिए एक मानचित्र से एक जोड़ी कॉपी करने के लिए क्या है के लिए एक मानचित्र कॉपी करने के लिए? मैं ऐसा कर रहा हूं इसलिए मैं बाद में वेक्टर को सॉर्ट कर सकता हूं।सी ++ कैसे एक वेक्टर

+2

बहुत अस्पष्ट सवाल – camh

+1

मैप्स हल कर रहे हैं। आपको यह निर्दिष्ट करना चाहिए कि आप किसी अन्य पैरामीटर को सॉर्ट करना चाहते हैं या किसी भिन्न कुंजी के साथ। अन्यथा सवाल स्वयं उत्तर दिया गया है: नहीं। –

उत्तर

19

यह आप क्या चाहते हैं करना चाहिए:

#include <iostream> 
#include <vector> 
#include <map> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

bool cmp(const pair<int, int> &p1, const pair<int, int> &p2) 
{ 
    return p1.second < p2.second; 
} 

int main() 
{ 
    map<int, int> m; 
    for(int i = 0; i < 10; ++i) 
     m[i] = i * -i; 

    vector<pair<int, int> > v; 
    copy(m.begin(), m.end(), back_inserter(v)); 

    sort(v.begin(), v.end(), cmp); 

    for(int i = 0; i < v.size(); ++i) 
     cout << v[i].first << " : " << v[i].second << endl; 
    return 0; 
} 
2

एक map भंडार एक जोड़ी - एक प्रमुख और एक मूल्य। आप किस भाग की प्रतिलिपि बनाना चाहते हैं? या, क्या आप दोनों को दो अलग-अलग vector एस कॉपी करना चाहते हैं?

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

template <class V> 
struct sort_by_val { 
    bool operator()(V const& l, V const& r) { 
     return // ... 
    } 
}; 

vector<pair<K, V> > outv(map.begin(), map.end()); 

sort(outv.begin(), outv.end(), sort_by_val()); 
+0

मैं दोनों को कॉपी करना चाहता हूं। एक बार ऐसा करने के बाद, मुझे यह समझने की ज़रूरत है कि वेक्टर में * दूसरे * मूल्य से वेक्टर को कैसे सॉर्ट करें। –

+0

+1, स्पष्ट और सरल समाधान। @ जैक: आपको वास्तव में मुख्य टिप्पणी में अपनी टिप्पणी में जानकारी डालनी चाहिए क्योंकि यह बेहद प्रासंगिक है - उदा। यह सभी को यह उल्लेख करने से रोका होगा कि मानचित्र पहले से ही उनके पहले तत्वों द्वारा क्रमबद्ध हैं। –

6

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

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

+0

भी आसान हो सकता है: आप मानचित्र के सीटीआर में एक तुलनित्र निर्दिष्ट कर सकते हैं। – foraidt

25
vector<pair<K,V> > v(m.begin(), m.end()); 

या

vector<pair<K,V> > v(m.size()); 
copy(m.begin(), m.end(), v.begin()); 

copy()<algorithm> में है।

+2

यह एक और अधिक सुरुचिपूर्ण और सरल लगता है – Ram

+1

हां, यह सबसे अच्छा है, खासकर पहले वाला। कुछ टिप्पणियां बताते हैं: यदि आपके पास 'typedef std :: map मैपटाइप 'है, तो आप वेक्टर' वेक्टर 'घोषित नहीं कर सकते हैं क्योंकि value_type' pair है जिसका कोई ऑपरेटर नहीं है और नहीं कर सकता वेक्टर में कॉपी किया जाना चाहिए।इसके अलावा, दूसरे उदाहरण में पहले वेक्टर के आकार को पार करना वास्तव में महत्वपूर्ण है (या तो कन्स्ट्रक्टर या रिजर्व के माध्यम से) क्योंकि कॉपी वेक्टर में स्थान आवंटित नहीं करेगा क्योंकि तत्व जोड़े जाते हैं और एक मजबूत मौका है कि आप दौड़ेंगे वेक्टर के प्रारंभिक आवंटन का अंत। –

+1

'प्रतिलिपि (एम .बीजिन(), एम.एंड(), v.begin()); 'मुझे एक सेगमेंटेशन फॉल्ट दिया। बस केह रहा हू। – yasith

2

मान लिया जाये कि आप कुंजी और मान की प्रतिलिपि बनाना चाहते:

std::map<Foo, Bar> m; 


// Map gets populated 
// (...) 


// Copying it to a new vector via the constructor 
std::vector<std::pair<Foo, Bar>> v(m.begin(), m.end()); 


// Copying it to an existing vector, erasing the contents 
v.assign(m.begin(), m.end()); 

// Copying it to the back of an existing vector 
v.insert(v.end(), m.begin(), m.end()); 
+0

वह अंतिम गलत है। शायद आपका मतलब v.insert (v.rbegin() आधार(), m.begin(), m.end()); ? – wilhelmtell

+0

whihelmtell - आपको ऐसा क्यों लगता है कि यह गलत है? मैंने अभी कोशिश की - यह ठीक काम करता है। –

+0

इसके बारे में सोचने के लिए आओ: v.rebegin()। बेस() एक ही इटरेटर को v.end() –

2

उद्देश्य सिर्फ कुंजी के बजाय प्रकार के आधार पर सॉर्ट करने के लिए है, तो , आप Boost::Bimap पर देखना चाह सकते हैं। यह आपको नक्शा जोड़ी के दोनों हिस्सों को चाबियों तक पहुंचने देता है। संभवतः आप दूसरी कुंजी के क्रम में पहले जितनी आसानी से इसे फिर से चालू कर सकते हैं।

0

के रूप में आप सम्मिलित आप एक अलग नक्शा उपयोग कर सकते हैं (या सेट) और प्रयोग को बदलने की छंटाई करने के लिए:

#include <map> 
#include <algorithm> 

typedef std::map<unsigned int, signed char> MapType1; 
typedef std::map<MapType1::mapped_type, MapType1::key_type> MapType2; 

struct SwapPair 
{ 
    MapType2::value_type operator()(MapType1::value_type const & v) 
    { 
    return std::make_pair (v.second, v.first); 
    } 
}; 

int main() 
{ 
    MapType1 m1; 
    for(int i = 0; i < 10; ++i) 
    m1[i] = i * -i; 

    MapType2 m2; 
    std::transform (m1.begin() 
     , m1.end() 
     , std::inserter (m2, m2.end()) 
     , SwapPair()); 
} 

मैं जोड़ने के लिए है कि तो यह बेहतर हो सकता है अगर आप इस एक बहुत सब करने की ज़रूरत भूल गया बस multi-index कंटेनर को बढ़ावा देने के लिए।

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