दो एसटीडी: वैक्टर


687

मैं दो std::vectorएस कैसे सम्‍मिलित करूं ?


5
दिए गए उत्तर वास्तव में संक्षिप्त नहीं हैं। वे एक प्रति संलग्न करते हैं। एक एसटीडी बनाने के लिए एक उपयोग (दक्षता के बिंदु के लिए) हो सकता है :: वेक्टर कॉन्कैटनेट विधि, हालांकि इसे नोड्स के प्रबंधन के कुछ परिष्कृत साझाकरण की आवश्यकता होगी और शायद यही कारण है कि ऐसा नहीं किया गया है।
19

8
@FauChristian: नहीं, दक्षता के दृष्टिकोण से उपयोग नहीं हो सकता है। वेक्टर मेमोरी निरंतर होनी चाहिए, इसलिए आपको जो सुझाव दिया जाता है वह असंभव है। यदि आप "नोड्स के प्रबंधन के कुछ परिष्कृत साझाकरण" चाहते थे, और यदि आप वेक्टर वर्ग को इस तरह से बदलना चाहते हैं, तो आप एक छल के साथ समाप्त होंगे। फिर भी सुझाए गए तरीके से मेमोरी का पुन: उपयोग करना बहुत मुश्किल है, हालांकि यह थोड़ा अधिक संभव होने लगेगा। मुझे नहीं लगता कि यह वर्तमान में लागू है। मुख्य बात यह है कि प्रबंधन नोड्स (एक छल) के इस तरह के बंटवारे में अंत नोड आंशिक रूप से खाली हो सकता है।
कुकी

4
@lecaruyer आपको एहसास है कि आपने सिर्फ एक प्रश्न को चिह्नित किया था जो दो साल पहले एक डुप्लिकेट के रूप में पूछा गया था
eshirima

9
I Am केवल एक ही सोच क्यों इस रूप में लागू नहीं है a + bया a.concat(b)मानक पुस्तकालय में? हो सकता है कि डिफ़ॉल्ट क्रियान्वयन सब-
ऑप्टिमल

9
विकास के वर्ष, किसी भी मुख्यधारा की भाषा के सबसे उन्नत ऑपरेटर-ओवरलोडिंग, एक टेम्प्लेटिंग सिस्टम जो भाषा की जटिलता को दोगुना करता है, और फिर भी इसका उत्तर v = v1 + v2 नहीं है;
Spike0xff

जवाबों:


727
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );

53
मैं केवल सबसे पहले प्रत्येक वेक्टर होल्ड के तत्वों की संख्या प्राप्त करने के लिए कोड जोड़ूंगा, और वेक्टर 1 को सबसे बड़ी होल्डिंग बनाऊंगा। क्या आपको ऐसा करना चाहिए अन्यथा आप बहुत सारी अनावश्यक नकल कर रहे हैं।
जो पेडा

34
मेरा एक सवाल है। अगर वेक्टर 1 और वेक्टर 2 एक ही वैक्टर हैं तो क्या यह काम करेगा?
अलेक्जेंडर रैफरटी

6
यदि आपके पास एक से कई वैक्टर हैं, तो क्या reserveपहले गंतव्य वेक्टर पर कॉल करना मददगार है ?
फहीम मिष्ठा

33
@AlexanderRafferty: केवल अगर vector1.capacity() >= 2 * vector1.size()। जब तक आपने फोन नहीं किया, तब तक यह असामान्य है std::vector::reserve()। अन्यथा वेक्टर फिर से जुड़ जाएगा, 2 और 3 के रूप में पारित किए गए पुनरावृत्तियों को अमान्य करना
ड्रू डॉर्मन

28
यह बहुत बुरा है मानक पुस्तकालय में एक अधिक रसीला अभिव्यक्ति नहीं है। .concatया +=कुछ और
nmr

193

यदि आप C ++ 11 का उपयोग कर रहे हैं, और तत्वों को केवल कॉपी करने के बजाय स्थानांतरित करना चाहते हैं, तो आप std::move_iteratorसम्मिलित (या प्रतिलिपि) के साथ उपयोग कर सकते हैं :

#include <vector>
#include <iostream>
#include <iterator>

int main(int argc, char** argv) {
  std::vector<int> dest{1,2,3,4,5};
  std::vector<int> src{6,7,8,9,10};

  // Move elements from src to dest.
  // src is left in undefined but safe-to-destruct state.
  dest.insert(
      dest.end(),
      std::make_move_iterator(src.begin()),
      std::make_move_iterator(src.end())
    );

  // Print out concatenated vector.
  std::copy(
      dest.begin(),
      dest.end(),
      std::ostream_iterator<int>(std::cout, "\n")
    );

  return 0;
}

यह चींटियों के साथ उदाहरण के लिए अधिक कुशल नहीं होगा, क्योंकि उन्हें स्थानांतरित करना उनकी नकल करने की तुलना में अधिक कुशल नहीं है, लेकिन अनुकूलित चाल के साथ डेटा संरचना के लिए, यह अनावश्यक स्थिति की नकल करने से बच सकता है:

#include <vector>
#include <iostream>
#include <iterator>

int main(int argc, char** argv) {
  std::vector<std::vector<int>> dest{{1,2,3,4,5}, {3,4}};
  std::vector<std::vector<int>> src{{6,7,8,9,10}};

  // Move elements from src to dest.
  // src is left in undefined but safe-to-destruct state.
  dest.insert(
      dest.end(),
      std::make_move_iterator(src.begin()),
      std::make_move_iterator(src.end())
    );

  return 0;
}

इस कदम के बाद, src के तत्व को अपरिभाषित लेकिन सुरक्षित-से-विनाश वाली स्थिति में छोड़ दिया गया है, और इसके पूर्व तत्वों को अंत में नए तत्व को नष्ट करने के लिए सीधे स्थानांतरित कर दिया गया था।


6
एसटीडी :: make_move_iterator () विधि ने मुझे तब मदद की जब एसटीडी को जोड़ने की कोशिश की गई :: एसटीडी के वैक्टर :: unique_ptr।
निट्सची

इसमें और इसमें क्या अंतर है std::move(src.begin(), src.end(), back_inserter(dest))?
kshenoy


77

या आप उपयोग कर सकते हैं:

std::copy(source.begin(), source.end(), std::back_inserter(destination));

यह पैटर्न उपयोगी है यदि दो वैक्टर में एक ही प्रकार की चीज नहीं है, क्योंकि आप एक प्रकार से दूसरे प्रकार में बदलने के लिए std :: back_inserter के बजाय कुछ का उपयोग कर सकते हैं।


7
प्रतिलिपि विधि ऐसा अच्छा तरीका नहीं है। यह कई बार push_back को कॉल करेगा, जिसका अर्थ है कि यदि बहुत सारे तत्वों को सम्मिलित करना है तो इसका मतलब कई वास्तविकताओं से हो सकता है। डालने का उपयोग करना बेहतर है क्योंकि वेक्टर कार्यान्वयन वास्तविकताओं से बचने के लिए कुछ अनुकूलन कर सकता है। यह कॉपी करने से पहले मेमोरी को आरक्षित कर सकता है
योगेश अरोड़ा

7
@ योगेश: दी गई, लेकिन कुछ भी नहीं है जो आपको reserveपहले कॉल करना बंद कर दे । कारण std::copyकभी-कभी उपयोगी होता है यदि आप इसके अलावा कुछ और उपयोग करना चाहते हैं back_inserter
रोजर लिप्सकॉम्ब

जब आप "एकाधिक आवंटन" कहते हैं, तो यह सच है - लेकिन आवंटन की संख्या सबसे खराब लॉग (अतिरिक्त प्रविष्टियों की संख्या) है - जिसका अर्थ है कि प्रविष्टि जोड़ने की लागत जोड़ी गई प्रविष्टियों की संख्या में स्थिर है। (मूल रूप से, इसके बारे में चिंता न करें जब तक कि प्रोफाइलिंग से पता चलता है कि आपको रिज़र्व की आवश्यकता है)।
मार्टिन बोनर

आप इसके बजाय ऐसा करने के लिए std :: ट्रांस्फ़ॉर्म का उपयोग करना चाह सकते हैं।
मार्टिन ब्रॉडहर्स्ट

1
प्रतिलिपि बहुत कुछ चूसती है, रिजर्व के साथ भी। वेक्टर :: डालने से सभी चेक बचेंगे
Denis Yaroshevskiy

63

C ++ 11 के साथ, मैं वेक्टर बी को एक में जोड़ना चाहूंगा:

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

जब aऔर bओवरलैप नहीं किया जाता है, और bअब और इस्तेमाल किया जा करने के लिए नहीं जा रहा है।


यह वह जगह है std::moveसे <algorithm>, नहीं हमेशा की तरह std::move से <utility>


10
अपरिभाषित व्यवहार यदि वास्तव में बी है (जो कि ठीक है यदि आप जानते हैं कि ऐसा कभी नहीं हो सकता है - लेकिन सामान्य प्रयोजन कोड में जागरूक होने के लायक है)।
मार्टिन बोनर

1
@MartinBonner उल्लेख करने के लिए धन्यवाद। संभवतः मुझे पुराने insertतरीके से वापस मुड़ जाना चाहिए जो सुरक्षित है।
Deqing

15
आह, अन्य std :: चाल। पहली बार देखने पर काफी उलझन में।
xaxxon

1
इस से अलग है insert()साथ move_iteratorरों? यदि हां, तो कैसे?
जीफिलो

1
मैंने एक नोट जोड़ा है कि std::moveहम यहां क्या बात कर रहे हैं, क्योंकि ज्यादातर लोग इस अधिभार को नहीं जानते हैं। आशा है कि यह एक सुधार है।
YSC


24

मैं पहले से उल्लेखित एक को पसंद करता हूं:

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

लेकिन अगर आप C ++ 11 का उपयोग करते हैं, तो एक और सामान्य तरीका है:

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

इसके अलावा, एक सवाल का हिस्सा नहीं है, लेकिन reserveबेहतर प्रदर्शन के लिए आवेदन करने से पहले उपयोग करना उचित है । और यदि आप वेक्टर को स्वयं के साथ समेट रहे हैं, तो इसे जलाए बिना यह विफल हो जाता है, इसलिए आपको हमेशा ऐसा करना चाहिए reserve


तो मूल रूप से आपको क्या चाहिए:

template <typename T>
void Append(std::vector<T>& a, const std::vector<T>& b)
{
    a.reserve(a.size() + b.size());
    a.insert(a.end(), b.begin(), b.end());
}

2
std::तर्क-निर्भर लुकअप के माध्यम से कटौती की जाती हैend(a)काफी होगा।
आशु

4
@ AD AD केवल तभी जोड़ेगा std::यदि प्रकार से aआता है std, जो सामान्य पहलू को हरा देता है।
पोटाटोस्वाटर

अच्छी बात। इस मामले में यह एक वेक्टर है तो यह वैसे भी काम करेगा, लेकिन हाँ यह एक बेहतर उपाय है।
आशु

std :: start () / end () संग्रह के लिए जोड़े गए (सरणियों की तरह) जो उन्हें सदस्य कार्यों के रूप में नहीं है। लेकिन सरणियों में भी सम्मिलित () सदस्य फ़ंक्शन नहीं होता है, और प्रश्न कहता है "क्या एक सम्मिलित () के साथ एक संग्रह है, लेकिन बिना शुरुआत () (जो std के साथ काम करता है :: start ())?"
जेम्स कुर्रान



9

कॉकटेल के आकार को जांचने के लिए एक सामान्य प्रदर्शन को बढ़ावा देना है। और बड़े वाले के साथ छोटे को मर्ज / इन्सर्ट करें।

//vector<int> v1,v2;
if(v1.size()>v2.size()) {
    v1.insert(v1.end(),v2.begin(),v2.end());
} else {
    v2.insert(v2.end(),v1.begin(),v1.end());
}

इतना सरल, फिर भी मैंने इसके बारे में कभी नहीं सोचा था!
ज़िमानो

2
नमूना कोड गलत है। में स्थित निर्दिष्ट करने के लिए v1.insert(v2.end()...एक पुनरावृत्ति का उपयोग कर रहा v2है v1
डेविड स्टोन

तुम भी एक त्वरित स्वैप का उपयोग कर सकते हैं। @DavidStone मैंने इसे संपादित किया ताकि समाप्‍त क्रम को बदला जा सके। क्या एक वेक्टर की शुरुआत में जोड़ना संभव है?
qwr

आप शुरुआत में सम्मिलित कर सकते हैं, लेकिन यह धीमा होगा। वास्तव में "संक्षिप्त" करने के लिए, हालांकि, आदेश आम तौर पर मायने रखता है, इसलिए आपको यही करना होगा।
डेविड स्टोन

7

यदि आप कंसीव करने वाले वैक्टर्स को कंफर्टेबल करना चाहते हैं, तो आप +=ऑपरेटर को ओवरलोड कर सकते हैं ।

template <typename T>
std::vector<T>& operator +=(std::vector<T>& vector1, const std::vector<T>& vector2) {
    vector1.insert(vector1.end(), vector2.begin(), vector2.end());
    return vector1;
}

तो आप इसे इस तरह से कॉल कर सकते हैं:

vector1 += vector2;

6

यदि आप मजबूत अपवाद गारंटी में रुचि रखते हैं (जब कॉपी कंस्ट्रक्टर अपवाद फेंक सकता है):

template<typename T>
inline void append_copy(std::vector<T>& v1, const std::vector<T>& v2)
{
    const auto orig_v1_size = v1.size();
    v1.reserve(orig_v1_size + v2.size());
    try
    {
        v1.insert(v1.end(), v2.begin(), v2.end());
    }
    catch(...)
    {
        v1.erase(v1.begin() + orig_v1_size, v1.end());
        throw;
    }
}

append_moveअगर सदिश तत्व की चाल निर्माणकर्ता फेंक सकता है (जो कि अभी भी संभावना नहीं है) लेकिन मजबूत गारंटी के साथ समान रूप से लागू नहीं किया जा सकता है।


क्या v1.erase(...फेंकना भी संभव नहीं है ?
कक्षा कंकाल

insertपहले से ही यह संभालती है। इसके अलावा, यह कॉल eraseएक के बराबर है resize
पोटाटोस्वाटर

मुझे यह पसंद है - धन्यवाद!
नेटर्सोज़

5

इसे अपनी हेडर फ़ाइल में जोड़ें:

template <typename T> vector<T> concat(vector<T> &a, vector<T> &b) {
    vector<T> ret = vector<T>();
    copy(a.begin(), a.end(), back_inserter(ret));
    copy(b.begin(), b.end(), back_inserter(ret));
    return ret;
}

और इसे इस तरह से उपयोग करें:

vector<int> a = vector<int>();
vector<int> b = vector<int>();

a.push_back(1);
a.push_back(2);
b.push_back(62);

vector<int> r = concat(a, b);

r में [1,2,62] शामिल होंगे


पता नहीं क्यों यह नीचे मतदान किया गया था। यह ऐसा करने का सबसे कुशल तरीका नहीं हो सकता है लेकिन यह गलत नहीं है और प्रभावी है।
leeor_net

4

यहाँ C ++ 11 चाल शब्दार्थ का उपयोग कर एक सामान्य उद्देश्य समाधान है:

template <typename T>
std::vector<T> concat(const std::vector<T>& lhs, const std::vector<T>& rhs)
{
    if (lhs.empty()) return rhs;
    if (rhs.empty()) return lhs;
    std::vector<T> result {};
    result.reserve(lhs.size() + rhs.size());
    result.insert(result.cend(), lhs.cbegin(), lhs.cend());
    result.insert(result.cend(), rhs.cbegin(), rhs.cend());
    return result;
}

template <typename T>
std::vector<T> concat(std::vector<T>&& lhs, const std::vector<T>& rhs)
{
    lhs.insert(lhs.cend(), rhs.cbegin(), rhs.cend());
    return std::move(lhs);
}

template <typename T>
std::vector<T> concat(const std::vector<T>& lhs, std::vector<T>&& rhs)
{
    rhs.insert(rhs.cbegin(), lhs.cbegin(), lhs.cend());
    return std::move(rhs);
}

template <typename T>
std::vector<T> concat(std::vector<T>&& lhs, std::vector<T>&& rhs)
{
    if (lhs.empty()) return std::move(rhs);
    lhs.insert(lhs.cend(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
    return std::move(lhs);
}

ध्यान दें कि यह appendआईएनजी से अलग कैसे है vector


4

आप अपना स्वयं का टेम्पलेट + ऑपरेटर के लिए तैयार कर सकते हैं:

template <typename T> 
inline T operator+(const T & a, const T & b)
{
    T res = a;
    res.insert(res.end(), b.begin(), b.end());
    return res;
}

अगली बात - बस उपयोग +:

vector<int> a{1, 2, 3, 4};
vector<int> b{5, 6, 7, 8};
for (auto x: a + b)
    cout << x << " ";
cout << endl;

यह उदाहरण आउटपुट देता है:

1 2 3 4 5 6 7 8

2
उपयोग करना T operator+(const T & a, const T & b)खतरनाक है, इसका उपयोग करना बेहतर है vector<T> operator+(const vector<T> & a, const vector<T> & b)
Matthieu H

4

C ++ 17std::merge से एक एल्गोरिथ्म है , जिसका उपयोग करना बहुत आसान है,

नीचे उदाहरण है:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    //DATA
    std::vector<int> v1{2,4,6,8};
    std::vector<int> v2{12,14,16,18};

    //MERGE
    std::vector<int> dst;
    std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));

    //PRINT
    for(auto item:dst)
        std::cout<<item<<" ";

    return 0;
}

2
मुझे नहीं लगता कि यह किसी भी उपयोग करने के लिए आसान है std::vector::insert, लेकिन यह कुछ अलग करता है: दो श्रेणियों को एक नई श्रेणी में विलय करना बनाम एक दूसरे के अंत में एक वेक्टर सम्मिलित करना। उत्तर में उल्लेख के लायक?
jb

4

यदि आपका लक्ष्य केवल रीड-ओनली उद्देश्यों के लिए मानों की सीमा पर पुनरावृति करना है, तो एक विकल्प दोनों वैक्टर को प्रॉक्सी (O (1)) के चारों ओर लपेटने के बजाय उन्हें (O (n)) कॉपी करने के लिए है, इसलिए उन्हें तुरंत देखा जाता है एक एकल के रूप में, एक सन्निहित।

std::vector<int> A{ 1, 2, 3, 4, 5};
std::vector<int> B{ 10, 20, 30 };

VecProxy<int> AB(A, B);  // ----> O(1)!

for (size_t i = 0; i < AB.size(); i++)
    std::cout << AB[i] << " ";  // ----> 1 2 3 4 5 10 20 30

अधिक जानकारी के लिए https://stackoverflow.com/a/55838758/2379625 देखें, जिसमें 'VecProxy' कार्यान्वयन के साथ-साथ पेशेवरों और विपक्ष भी शामिल हैं।


3
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));

6
हालांकि यह कोड स्निपेट समस्या को हल कर सकता है, यह इस बात की व्याख्या नहीं करता है कि यह प्रश्न का उत्तर क्यों या कैसे देता है। कृपया अपने कोड के लिए एक स्पष्टीकरण शामिल करें , क्योंकि यह वास्तव में आपके पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। ध्वजवाहक / समीक्षक: केवल इस तरह के उत्तर के रूप में कोड के लिए, नीचे, हटाएं नहीं! (नोट: यह उत्तर वास्तव में एक स्पष्टीकरण करने के लिए पर्याप्त सरल हो सकता है, और इस प्रकार नीचे की ओर, अनावश्यक है। आप अभी भी अधिक NAA / VLQ झंडे को रोकने के लिए स्पष्टीकरण जोड़ना चाह सकते हैं।)
स्कॉट वेल्डन

2

मैंने इस फ़ंक्शन को कार्यान्वित किया है जो किसी भी संख्या में कंटेनरों को समेटता है, प्रतिद्वंद्वियों-संदर्भों से आगे बढ़ता है और अन्यथा कॉपी करता है

namespace internal {

// Implementation detail of Concatenate, appends to a pre-reserved vector, copying or moving if
// appropriate
template<typename Target, typename Head, typename... Tail>
void AppendNoReserve(Target* target, Head&& head, Tail&&... tail) {
    // Currently, require each homogenous inputs. If there is demand, we could probably implement a
    // version that outputs a vector whose value_type is the common_type of all the containers
    // passed to it, and call it ConvertingConcatenate.
    static_assert(
            std::is_same_v<
                    typename std::decay_t<Target>::value_type,
                    typename std::decay_t<Head>::value_type>,
            "Concatenate requires each container passed to it to have the same value_type");
    if constexpr (std::is_lvalue_reference_v<Head>) {
        std::copy(head.begin(), head.end(), std::back_inserter(*target));
    } else {
        std::move(head.begin(), head.end(), std::back_inserter(*target));
    }
    if constexpr (sizeof...(Tail) > 0) {
        AppendNoReserve(target, std::forward<Tail>(tail)...);
    }
}

template<typename Head, typename... Tail>
size_t TotalSize(const Head& head, const Tail&... tail) {
    if constexpr (sizeof...(Tail) > 0) {
        return head.size() + TotalSize(tail...);
    } else {
        return head.size();
    }
}

}  // namespace internal

/// Concatenate the provided containers into a single vector. Moves from rvalue references, copies
/// otherwise.
template<typename Head, typename... Tail>
auto Concatenate(Head&& head, Tail&&... tail) {
    size_t totalSize = internal::TotalSize(head, tail...);
    std::vector<typename std::decay_t<Head>::value_type> result;
    result.reserve(totalSize);
    internal::AppendNoReserve(&result, std::forward<Head>(head), std::forward<Tail>(tail)...);
    return result;
}

1

यदि आप जिस चीज़ की तलाश कर रहे हैं, वह एक वेक्टर को निर्माण के बाद दूसरे में जोड़ने का एक तरीका है, vector::insertतो आपका सबसे अच्छा दांव है, जैसा कि कई बार उत्तर दिया गया है, उदाहरण के लिए:

vector<int> first = {13};
const vector<int> second = {42};

first.insert(first.end(), second.cbegin(), second.cend());

अफसोस की बात है कि निर्माण का कोई तरीका नहीं है const vector<int>, जैसा कि ऊपर आपको निर्माण करना चाहिए और फिर insert


यदि आप वास्तव में जिस चीज की तलाश कर रहे हैं, वह इन दो vector<int>एस के संयोजन को रखने के लिए एक कंटेनर है , तो आपके लिए कुछ बेहतर उपलब्ध हो सकता है, यदि:

  1. आपके पास vectorआदिम हैं
  2. आपकी समाहित प्रधानताएँ आकार में 32-बिट या छोटी हैं
  3. आपको एक constकंटेनर चाहिए

यदि उपरोक्त सभी सत्य हैं, तो मैं सुझाव दूंगा कि आपके मैच में basic_stringकौन char_typeआदिम के आकार का उपयोग करता है vectorstatic_assertइन आकारों के अनुरूप रहने के लिए आपको अपने कोड में एक को शामिल करना चाहिए :

static_assert(sizeof(char32_t) == sizeof(int));

इस सच को पकड़ कर आप बस कर सकते हैं:

const u32string concatenation = u32string(first.cbegin(), first.cend()) + u32string(second.cbegin(), second.cend());

stringऔर vectorआप के बीच के अंतर के बारे में अधिक जानकारी के लिए यहाँ देख सकते हैं: https://stackoverflow.com/a/35558008/2642059

इस कोड के जीवंत उदाहरण के लिए आप यहां देख सकते हैं: http://ideone.com/7Iww3I


0

यह समाधान थोड़ा जटिल हो सकता है, लेकिन boost-rangeइसमें कुछ अन्य अच्छी चीजें भी हैं।

#include <iostream>
#include <vector>
#include <boost/range/algorithm/copy.hpp>

int main(int, char**) {
    std::vector<int> a = { 1,2,3 };
    std::vector<int> b = { 4,5,6 };
    boost::copy(b, std::back_inserter(a));
    for (auto& iter : a) {
        std::cout << iter << " ";
    }
    return EXIT_SUCCESS;
}

अक्सर लोगों का इरादा वेक्टर को संयोजित करना होता है aऔर bबस कुछ ऑपरेशन करने से अधिक पुनरावृति होती है। इस मामले में, हास्यास्पद सरल joinकार्य है।

#include <iostream>
#include <vector>
#include <boost/range/join.hpp>
#include <boost/range/algorithm/copy.hpp>

int main(int, char**) {
    std::vector<int> a = { 1,2,3 };
    std::vector<int> b = { 4,5,6 };
    std::vector<int> c = { 7,8,9 };
    // Just creates an iterator
    for (auto& iter : boost::join(a, boost::join(b, c))) {
        std::cout << iter << " ";
    }
    std::cout << "\n";
    // Can also be used to create a copy
    std::vector<int> d;
    boost::copy(boost::join(a, boost::join(b, c)), std::back_inserter(d));
    for (auto& iter : d) {
        std::cout << iter << " ";
    }
    return EXIT_SUCCESS;
}

बड़े वैक्टर के लिए यह एक फायदा हो सकता है, क्योंकि कोई नकल नहीं है। इसका उपयोग एक सामान्य से अधिक कंटेनर में आसानी से कॉपी करने के लिए भी किया जा सकता है।

किसी कारण से ऐसा कुछ नहीं है boost::join(a,b,c), जो उचित हो सकता है।


0

आप इसे पॉलीमॉर्फिक प्रकार के उपयोग के लिए टेम्पलेट का उपयोग करके पूर्व-लागू एसटीएल एल्गोरिदम के साथ कर सकते हैं।

#include <iostream>
#include <vector>
#include <algorithm>

template<typename T>

void concat(std::vector<T>& valuesa, std::vector<T>& valuesb){

     for_each(valuesb.begin(), valuesb.end(), [&](int value){ valuesa.push_back(value);});
}

int main()
{
    std::vector<int> values_p={1,2,3,4,5};
    std::vector<int> values_s={6,7};

   concat(values_p, values_s);

    for(auto& it : values_p){

        std::cout<<it<<std::endl;
    }

    return 0;
}

यदि आप इसे आगे ( clear()विधि) उपयोग नहीं करना चाहते हैं तो आप दूसरे वेक्टर को साफ़ कर सकते हैं ।


-1

एक में लूप के std::vector-sसाथ दो समेटें ।forstd::vector

उदाहरण:

std::vector <int> v1 {1, 2, 3};//declare vector1
std::vector <int> v2 {4, 5};//declare vector2
std::vector <int> suma;//declare vector suma

for(auto i = 0; i < v1.size()-1;i++)//for loop 1
{
     suma.push_back(v1[i]);
}

for(auto i = 0; i< v2.size()-1;i++)/for loop 2
{
     suma.push_back(v2[i]);
}

for(auto i = 0; i < suma.size(); i++)//for loop 3-output
{
     std::cout<<suma[i];
}

इस कोड को लिखें main()


आप forलूप गलत हैं। एक वेक्टर में मान्य अनुक्रमित 0 से होते हैं size()-1। आप लूप समाप्ति शर्तों i < v1.size()का उपयोग करना चाहिए , <नहीं का उपयोग कर <=। गलत स्थिति का उपयोग करके कंटेनर के बाहर मेमोरी एक्सेस की जाती है।
ब्लास्टफर्न

काम नहीं करने के अलावा, यह कोड बहुत अधिक गैर-मुहावरेदार है। आपको कम से कम autoमैनुअल इंडेक्सिंग के बजाय पुनरावृत्तियों का उपयोग करना चाहिए । आप इस बात की परवाह नहीं करते हैं कि आप किस इंडेक्स को केवल इतना समझ रहे हैं कि यह क्रमिक रूप से किया जाता है।
तारिक वेलिंग

क्या आप बता सकते हैं कि आप size()-1अपनी दो लूप स्थितियों में उपयोग क्यों कर रहे हैं? यह पिछले वेक्टर तत्वों को छोड़ देता है। तीसरा लूप अब केवल एक ही सही है।
ब्लास्टफर्न

-3

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

विधि 1: नए वेक्टर को उसके आकार के साथ असाइन करें दो मूल वैक्टर के आकार का योग है।

vector<int> concat_vector = vector<int>();
concat_vector.setcapacity(vector_A.size() + vector_B.size());
// Loop for copy elements in two vectors into concat_vector

विधि 2: वेक्टर B के तत्वों को जोड़ / जोड़कर वेक्टर A को जोड़िए।

// Loop for insert elements of vector_B into vector_A with insert() 
function: vector_A.insert(vector_A .end(), vector_B.cbegin(), vector_B.cend());

4
आपका जवाब क्या जोड़ता है जो पहले से ही अन्य उत्तरों में प्रदान नहीं किया गया है?
Mat

13
@ मट: बोल्ड किरदार।
Marcv81

यदि मूल वेक्टर (ओं) की अब आवश्यकता नहीं है, तो इसका उपयोग करना बेहतर हो सकता है std::move_iteratorताकि कॉपी किए गए तत्वों को स्थानांतरित किया जा सके। (देखें en.cppreference.com/w/cpp/iterator/move_iterator )।
tmlen

क्या है setcapacity? क्या है function: ?
एलएफ

@ मुझे लगता है कि वह resizeविधि के बारे में बात कर रहा है ।
Matthieu एच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.