2011-02-24 25 views
15

को मैं एक नक्शा है कि इसकॉपी std :: नक्शा डेटा एक और नक्शा

struct A 
{ 
    int A; 
    int B; 
}; 
typedef map<int,A> Amap; 

तरह परिभाषित किया है तो मैं Amap1 है और मैं Amap2

A a....; 
Amap Amap1,Amap2; 
Amap1[1]=a1; 
Amap1[2]=a2; 
Amap1[3]=a3; 
Amap2.insert(Amap1.begin(), Amap1.end()); 

पर प्रतिलिपि चाहते हैं कभी कभी यह काम ठीक से किया है, कभी-कभी यह केवल चाबियाँ और मान 0 की प्रतिलिपि बनाता है। मेरी गलती कहां है?

उत्तर

34

सबसे पहले, यह std::map है, है ना stl::map :)

और दूसरा नकल एक नक्शा दूसरे करने के लिए ऑपरेटर = या कॉपी निर्माता के साथ किया जा सकता है।

उदा

map<X, Y> mp1; 
//fill mp1 with data 
map<X, Y> mp2(mp1); //mp2 is a copy of mp1 (via copy-construction) 
map<X, Y> mp3; 
mp3 = mp2; // mp3 is also a copy of mp2 (via copy-assignment) 
+0

@ भेड़िया: उन दोनों विधियों को उत्तर में प्रस्तुत किया गया है। यह एक सहयोगी रूप से संपादित समुदाय है, यदि आप उत्तर में जोड़ना चाहते हैं, तो इसे संपादित करने में संकोच न करें। –

+0

@ वुल्फ: कृपया अन्य लोगों के उत्तरों को काफी हद तक संशोधित न करें, खासतौर से उन पांच साल पहले लिखे गए जिन्हें पहले से ही लोगों द्वारा उखाड़ फेंक दिया गया है और ओपी द्वारा स्वीकार किया गया है। अपना खुद का, प्रतिस्पर्धात्मक उत्तर लिखने के लिए स्वतंत्र महसूस करें। –

+0

@LightnessRacesinOrbit मैंने इसके लिए पूछा और ओपी ने मुझे स्पष्ट रूप से यह दिया: * 'इसे संपादित करने के लिए स्वतंत्र महसूस करें' * – Wolf

13

कोड आप ऊपर पोस्ट किया है सही ढंग से यह सोचते हैं कि Amap2 खाली है काम करेंगे। यदि आप insert को map में एक कुंजी/मान जोड़ी का प्रयास करते हैं जो पहले से ही उस कुंजी को रखता है, तो पुराना मान रखा जाएगा और नया एक त्याग दिया जाएगा। कारण है कि, अगर तुम,

Amap2.insert(Amap1.begin(), Amap1.end()); 

कुछ परिस्थितियों तुम सब कुछ पर कॉपी नहीं हो सकता है के रूप में इरादा में लिखने क्योंकि डुप्लिकेट चाबी कॉपी नहीं करेंगे।

सेट करने के लिए Amap2Amap1 के बराबर है, बस असाइनमेंट ऑपरेटर का उपयोग करें:

Amap2 = Amap1; 

यह आँख बंद करके Amap2 की सामग्री को निकाल देगा, हालांकि, तो सावधान जब यह कर सकता है।

यदि आप करना चाहते हैं तो Amap2 से में सभी कुंजी/मान जोड़े को Amap1 में जोड़ें जो मौजूदा कुंजी/मान जोड़े को पूरी तरह से ओवरराइड करता है, आप निम्न तर्क का उपयोग करके ऐसा कर सकते हैं। विचार यहाँ mergesort के पीछे तर्क के समान है - हम क्रमबद्ध मूल्यों के दृश्यों के रूप में नक्शे का इलाज और उसके बाद लगातार दोनों एक साथ मिश्रण:

void MergeMaps(map<int, A>& lhs, const map<int, A>& rhs) { 
    map<int, A>::iterator lhsItr = lhs.begin(); 
    map<int, A>::const_iterator rhsItr = rhs.begin(); 

    while (lhsItr != lhs.end() && rhsItr != rhs.end()) { 
     /* If the rhs value is less than the lhs value, then insert it into the 
      lhs map and skip past it. */ 
     if (rhsItr->first < lhsItr->first) { 
      lhs.insert(lhsItr, *rhsItr); // Use lhsItr as a hint. 
      ++rhsItr; 
     } 
     /* Otherwise, if the values are equal, overwrite the lhs value and move both 
      iterators forward. */ 
     else if (rhsItr->first == lhsItr->first) { 
      lhsItr->second = rhsItr->second; 
      ++lhsItr; ++rhsItr; 
     } 
     /* Otherwise the rhs value is bigger, so skip past the lhs value. */ 
     else 
      ++lhsItr; 

    } 

    /* At this point we've exhausted one of the two ranges. Add what's left of the 
     rhs values to the lhs map, since we know there are no duplicates there. */ 
    lhs.insert(rhsItr, rhs.end()); 
} 
इस के साथ

, आप लिख सकते हैं

MergeMaps(Amap1, Amap2); 

कॉपी करने के लिए Amap2 से Amap1 में सभी कुंजी/मूल्य जोड़े।

आशा है कि इससे मदद मिलती है!

+2

यदि मैं यह सुनिश्चित करना चाहता था कि मौजूदा कुंजी ओवरराइट की गई हैं तो 2 विकल्प हैं जिन्हें मैं चुन सकता हूं: मैं या तो std :: प्रतिलिपि का उपयोग करता हूं लेकिन 'std :: inserter के बजाय 'मैं एक कस्टम लिखूंगा जो' ऑपरेटर [] 'का इस्तेमाल करता था। वैकल्पिक 2-लाइनर हालांकि संभवतः काफी कुशल नहीं है, तो प्रतिलिपि बनाने के लिए नियमित रूप से सम्मिलित lhsItr कॉपी करें और फिर स्वैप करें। – CashCow

+1

@CashCow: कस्टम डालने की तुलना में मेरे दृष्टिकोण का मुख्य लाभ यह है कि ब्रैकेट औसत केस ओ (एलजी एन) में चलते हैं जबकि मेरे द्वारा पोस्ट किया गया कोड रैखिक समय में चलाना चाहिए, क्योंकि डालने का अच्छा कार्यान्वयन पास के इटरेटर होने से संकेत। – templatetypedef

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