2008-11-24 16 views
30

के साथ एक वेक्टर का विस्तार करता है मैं पहली बार एसटीएल के साथ काम कर रहे सी ++ भूमि में सी/पायथन प्रोग्रामर हूं।सी ++ किसी अन्य वेक्टर

>>> v = [1, 2, 3] 
>>> v_prime = [4, 5, 6] 
>>> v.extend(v_prime) 
>>> print(v) 
[1, 2, 3, 4, 5, 6] 

मैं वर्तमान में सी में वैक्टर विस्तार करने के लिए इस एल्गोरिथम दृष्टिकोण का उपयोग ++:

अजगर में, एक और सूची के साथ एक सूची का विस्तार .extend विधि का उपयोग करता

v.resize(v.size() + v_prime.size()); 
copy(v_prime.begin(), v_prime.end(), v.rbegin()); 

इस का प्रामाणिक तरीका है वैक्टर का विस्तार, या यदि कोई आसान तरीका है कि मैं याद कर रहा हूं?

+0

संभावित डुप्लिकेट http://stackoverflow.com/questions/201718/concatenating-two-stdvectors) –

उत्तर

45

here से

// reserve() is optional - just to improve performance 
v.reserve(v.size() + distance(v_prime.begin(),v_prime.end())); 
v.insert(v.end(),v_prime.begin(),v_prime.end()); 
+0

मुझे नहीं लगता कि यादृच्छिक एक्सेस इनपुट इटरेटर्स के लिए वेक्टर :: डालने का एक विशेषज्ञता है, इसलिए यदि प्रदर्शन महत्वपूर्ण है, तो आरक्षित() पहले। –

+9

वीसी ++ 9.0 और जीसीसी 4.3.2 दोनों आंतरिक रूप से इटरेटर श्रेणी निर्धारित करते हैं, इसलिए आपको आरक्षित करने की आवश्यकता नहीं है। –

+12

मुझे पता है कि यह 8 साल का है, लेकिन क्या कोई कारण है कि आपने 'v_prime.size() 'के बजाय' दूरी() 'का उपयोग क्यों किया? – Holt

18
copy(v_prime.begin(), v_prime.end(), back_inserter(v)); 
+0

मुझे लगता है कि अंतरिक्ष को अभी भी आरक्षित होना चाहिए() - डी प्रदर्शन को बेहतर बनाने के लिए –

+1

+1, क्योंकि प्रश्नकर्ता ने "सबसे सरल", "सबसे तेज़" नहीं पूछा, इसलिए अंतरिक्ष को सुरक्षित करना (विकल्प के रूप में उल्लेख करने के लायक होने पर) अनावश्यक है। –

+0

मुझे लगता है कि डिमिट्री समाधान दोनों सरल और तेज़ है। इस लड़के के लिए अपवित्र :) –

1

मैं सी ++ 14, जहां वेक्टर के प्रत्येक तत्व के लिए एक समर्थित चाल अर्थ विज्ञान संलग्न किया जा करने के लिए extend समारोह के दो अलग-अलग रूपों की जरूरत है।

vec आपका v है, और ext आपका v_prime है।

/** 
* Extend a vector with elements, without destroying source one. 
*/ 
template<typename T> 
void vector_extend(std::vector<T> &vec, const std::vector<T> &ext) { 
    vec.reserve(vec.size() + ext.size()); 
    vec.insert(std::end(vec), std::begin(ext), std::end(ext)); 
} 

/** 
* Extend a vector with elements with move semantics. 
*/ 
template<typename T> 
void vector_extend(std::vector<T> &vec, std::vector<T> &&ext) { 
    if (vec.empty()) { 
     vec = std::move(ext); 
    } 
    else { 
     vec.reserve(vec.size() + ext.size()); 
     std::move(std::begin(ext), std::end(ext), std::back_inserter(vec)); 
     ext.clear(); 
    } 
} 
3

अपने लक्ष्य को प्राप्त करने के कई तरीके हैं।

std :: वेक्टर :: सम्मिलित

वेक्टर निर्दिष्ट स्थान पर तत्व से पहले नए तत्व डालने, प्रभावी ढंग से डाला तत्वों की संख्या से कंटेनर के आकार में वृद्धि द्वारा बढ़ाया जा सकता। आप नीचे दिए गए दृष्टिकोणों में से एक का पालन कर सकते हैं। दूसरा संस्करण सी ++ 11 का उपयोग करता है और इसे अधिक सामान्य उत्तर के रूप में माना जा सकता है, क्योंकि बी भी सरणी हो सकता है।

a.insert(a.end(), b.begin(), b.end()); 
a.insert(std::end(a), std::begin(b), std::end(b)); 

कभी-कभी उपयोग में यह std :: vector :: insert का उपयोग करने से पहले आरक्षित फ़ंक्शन का उपयोग करने का सबसे अच्छा अभ्यास है। std :: vector :: रिजर्व फ़ंक्शन कंटेनर की क्षमता को उस मान पर बढ़ाता है जो new_cap के बराबर या बराबर है। यदि new_cap वर्तमान क्षमता() से अधिक है, तो नया संग्रहण आवंटित किया जाता है, अन्यथा विधि कुछ भी नहीं करती है।

a.reserve(a.size() + distance(b.begin(), b.end())); 

रिजर्व फ़ंक्शन का उपयोग आवश्यक नहीं है लेकिन सलाह दी जा सकती है। और यदि आप बार-बार वेक्टर में डालने के लिए आरक्षित करते हैं तो रिजर्व का उपयोग करना सबसे अच्छा है जिसके लिए आप अंतिम आकार जानते हैं, और वह आकार बड़ा है। अन्यथा, एसटीएल को आवश्यकतानुसार अपने वेक्टर को बढ़ाना बेहतर है।

std :: कॉपी

std :: नकल है कि आप अपने लक्ष्य को प्राप्त करने पर विचार कर सकते दूसरा विकल्प है। यह फ़ंक्शन परिणाम से शुरू होने वाली सीमा में तत्वों (पहले, अंतिम) में तत्वों की प्रतिलिपि बनाता है।

std::copy (b.begin(), b.end(), std::back_inserter(a)); 

हालांकि std :: प्रतिलिपि का उपयोग,) std :: वेक्टर के उपयोग :: डालने (की तुलना में धीमी है, क्योंकि std :: प्रतिलिपि() के लिए पर्याप्त स्थान आरक्षित नहीं कर सकते से पहले हाथ (यदि ऐसा नहीं होता वेक्टर तक पहुंच है, केवल एक इटरेटर के पास है), जबकि std :: vector :: insert(), सदस्य कार्य होने के नाते, कर सकते हैं। उस std :: प्रतिलिपि के कारण std :: vector :: insert का उपयोग करने से वास्तव में धीमा है। ज्यादातर लोग, इस परिदृश्य को जानने के बिना std :: प्रतिलिपि का उपयोग करते हैं।

बढ़ावा :: push_back

तीसरा विकल्प है कि आप विचार कर सकते हैं को बढ़ावा देने के push_back समारोह का उपयोग है।

boost::push_back(a, b); 
1

std::vector::insert का उपयोग करना;

A.reserve(A.size() + B.size()); 
A.insert(A.end(), B.begin(), B.end()); 

reserve() वैकल्पिक है, लेकिन यह प्रदर्शन को बेहतर बनाने में मदद करता है का उपयोग कर।


convienent कोड जनरेटर कीमती सेकंड बचाने के लिए: ([दो std :: वैक्टर श्रृंखलाबद्ध] की

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script><script src="https://cdn.jsdelivr.net/clipboard.js/1.6.0/clipboard.min.js"></script><script>function generateCode(){codeTemplate="{0}.reserve({0}.size() + {1}.size()); \n{0}.insert({0}.end(), {1}.begin(), {1}.end());",first=document.getElementById("1").value,second=document.getElementById("2").value,""==first&&(first="A"),""==second&&(second="B"),document.getElementById("c").innerHTML=String.format(codeTemplate,first,second)}String.format||(String.format=function(a){var b=Array.prototype.slice.call(arguments,1);return a.replace(/{(\d+)}/g,function(a,c){return"undefined"!=typeof b[c]?b[c]:a})});</script><div class="A" style="margin:3% 10% 1% 10%;"><label for="1">First vector name:</label><input id="1"/><br/><label for="1">Second vector name:</label><input id="2"/><div class="D"><a class="waves-effect waves-light btn red col" onclick="generateCode();" style="margin:0 0 4% 0;">Generate Code</a></div><textarea id="c" onclick="this.select()" style="border:none;height:auto;overflow: hidden;font-family:Consolas,Monaco;">A.reserve(A.size() + B.size());&#13;&#10;A.insert(A.end(), B.begin(), B.end());</textarea></div>