দুটি স্ট্যান্ড :: ভেক্টর সংঘবদ্ধ


687

আমি কীভাবে দু'জনকে সম্মতি জানাতে পারি std::vector?


5
প্রদত্ত উত্তরগুলি আসলে একত্রিত হয় না। তারা একটি অনুলিপি সংযোজন। একটি স্ট্যান্ড :: ভেক্টর কনকেনেটেট পদ্ধতি তৈরি করার জন্য (দক্ষতার দৃষ্টিকোণের জন্য) কোনও ব্যবহার থাকতে পারে, তবে এর জন্য নোডগুলির পরিচালনার কিছু পরিশীলিত ভাগাভাগির প্রয়োজন হবে এবং সে কারণেই সম্ভবত এটি করা হয়নি।
ফৌচ্রিস্টিয়ান

8
@ ফৌক্রিশিয়ান: না, দক্ষতার দৃষ্টিকোণ থেকে ব্যবহার নাও হতে পারে। ভেক্টর মেমরি অবশ্যই অবিচ্ছিন্ন হতে পারে, তাই আপনার যা প্রস্তাবিত তা অসম্ভব। আপনি যদি "নোডগুলির পরিচালনা সম্পর্কে কিছু পরিশীলিত ভাগ করে নেওয়ার" চেয়েছিলেন এবং যদি আপনি ভেক্টর শ্রেণিটি এমনভাবে পরিবর্তন করতে চান তবে আপনি একটি প্রানীর সাথে সমাপ্ত হতেন। তারপরেও প্রস্তাবিতভাবে মেমরিটিকে পুনরায় ব্যবহার করা খুব কঠিন, যদিও এটি কিছুটা সম্ভবপর হতে শুরু করবে। আমি মনে করি না এটি বর্তমানে কার্যকর হয়েছে is মূল বিষয়টি হ'ল ম্যানেজমেন্ট নোডের ভাগ করে নেওয়ার ক্ষেত্রে (একটি ডেকি) শেষ নোডটি আংশিক খালি থাকতে পারে।
কুকি

4
@ ক্যারুয়ায়ার আপনি বুঝতে পেরেছেন যে আপনি ডুপ্লিকেট হিসাবে দু'বছর আগে জিজ্ঞাসা করা প্রশ্নটি সবেমাত্র চিহ্নিত করেছেন
ইশিরিমা

9
আমি কি কেবলই ভাবছি যে কেন এটি স্ট্যান্ডার্ড লাইব্রেরিতে a + bবা হিসাবে প্রয়োগ করা হয় না a.concat(b)? হতে পারে ডিফল্ট বাস্তবায়ন suboptimal হবে, কিন্তু প্রতিটি অ্যারে সংক্ষিপ্ত বিবরণ মাইক্রো অনুকূলিতকরণ করা প্রয়োজন হয় না
oesiskar

9
বিবর্তনের বছরগুলি, যে কোনও মূলধারার ভাষার সর্বাধিক উন্নত অপারেটর-ওভারলোডিং, একটি টেম্প্লেটিং সিস্টেম যা ভাষার জটিলতা দ্বিগুণ করে, এবং এখনও উত্তরটি v = v1 + v2 নয়;
স্পাইক0xff

উত্তর:


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

53
আমি কেবল প্রথমে প্রতিটি ভেক্টরকে ধারণ করে এমন উপাদানগুলির সংখ্যা পাওয়ার জন্য কোড যুক্ত করব এবং ভেক্টর 1টিকে সর্বাধিক হোল্ডিং হিসাবে সেট করবো। অন্যথায় আপনার করা উচিত আপনি প্রচুর অপ্রয়োজনীয় অনুলিপি করছেন।
জো পাইনেদা

34
আমার একটা প্রশ্ন আছে. ভেক্টর 1 এবং ভেক্টর 2 একই ভেক্টর হলে এই কাজ করবে?
আলেকজান্ডার রাফের্টি

6
আপনি যদি একাধিক ভেক্টরকে এক সাথে সংযুক্ত reserveকরে থাকেন তবে গন্তব্য ভেক্টরটিকে প্রথমে কল করা কি সহায়ক ?
ফাহিম মিঠা

33
@ আলেকজান্ডাররাফের্টি: কেবলমাত্র যদি vector1.capacity() >= 2 * vector1.size()। আপনি না ডাকলে কোনটি এপিক্যাল std::vector::reserve()। অন্যথায় ভেক্টর পুনরায় সরে যাবে, 2 এবং 3 পরামিতি হিসাবে পাস করা পুনরাবৃত্তিগুলি অকার্যকর করবে
ড্রউ ডোরম্যান

28
এটি খুব খারাপ যে স্ট্যান্ডার্ড লাইব্রেরিতে আরও সংক্ষিপ্ত বিবরণ নেই। .concatবা +=কিছু
nmr

193

আপনি যদি সি ++ 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;
}

সরানোর পরে, এসআরসি-র উপাদানটি একটি অপরিজ্ঞাত তবে নিরাপদ-থেকে-ধ্বংসাত্মক অবস্থায় ফেলে রাখা হয়েছে এবং এর পূর্বের উপাদানগুলি সরাসরি শেষের দিকে লক্ষ্যটির নতুন উপাদানে স্থানান্তরিত হয়েছিল।


6
Std :: make_move_iterator () পদ্ধতিটি আমাকে std :: vectors এর std :: অনন্য_পিটারের সাথে সংযুক্ত করার চেষ্টা করার সময় সহায়তা করেছিল।
নিটসচি

এই এবং এর মধ্যে পার্থক্য কি std::move(src.begin(), src.end(), back_inserter(dest))?
kshenoy


77

অথবা আপনি ব্যবহার করতে পারেন:

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

এই প্যাটার্নটি কার্যকর যদি দুটি ভেক্টর একই ধরণের জিনিস না রাখে, কারণ আপনি স্ট্যান্ড :: ব্যাক_ইনসেটর পরিবর্তে কিছু ব্যবহার করতে পারেন এক প্রকার থেকে অন্য রূপে রূপান্তর করতে।


7
অনুলিপি পদ্ধতি একটি ভাল উপায় না। এটি पुश_ব্যাক একাধিক সময় কল করবে যার অর্থ হ'ল যদি প্রচুর পরিমাণে উপাদান inোকাতে হয় তবে এর অর্থ একাধিক পুনঃনির্ধারণ হতে পারে। সন্নিবেশ ব্যবহার করা আরও ভাল কারণ ভেক্টর বাস্তবায়ন পুনরায় প্রত্যাশা এড়াতে কিছু অপ্টিমাইজেশন করতে পারে। এটি অনুলিপি করা শুরুর আগে স্মৃতি সংরক্ষণ করতে পারে
যোগেশ অরোরা

7
@ যোগেশ: মঞ্জুর হয়েছে, তবে আপনাকে reserveপ্রথমে কল করা কিছুতেই থামছে না । std::copyআপনি ব্যতীত অন্য কিছু ব্যবহার করতে চাইলে কারণটি কখনও কখনও দরকারী back_inserter
রজার লিপসক্বে

আপনি যখন "একাধিক বরাদ্দ" বলছেন, এটি সত্য - তবে বরাদ্দের সংখ্যাটি সবচেয়ে খারাপ লগের (যুক্ত হওয়া এন্ট্রিগুলির সংখ্যা) - যার অর্থ একটি এন্ট্রি যোগ করার ব্যয় যুক্ত হওয়া এন্ট্রিগুলির সংখ্যাতে স্থির থাকে। (মূলত, প্রোফাইলিং আপনার রিজার্ভের প্রয়োজন না দেখলে এটি নিয়ে চিন্তা করবেন না)।
মার্টিন বোনার

পরিবর্তে এটি করার জন্য আপনি std :: রূপান্তর ব্যবহার করতে চাইতে পারেন।
মার্টিন ব্রডহর্স্ট

1
অনুলিপি এমনকি প্রচুর রিজার্ভ সহ চুষে ফেলে। ভেক্টর :: সন্নিবেশ সমস্ত চেক এড়াতে হবে: quick-bench.com/bLJO4OfkAzMcWia7Pa80ynwmAIA
ডেনিস

63

সি ++ 11 দিয়ে আমি ভেক্টর বি কে যুক্ত করতে পছন্দ করব:

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

কখন aএবং bওভারল্যাপ bকরা হবে না এবং আর ব্যবহার করা হবে না।


এই std::moveথেকে <algorithm>, না স্বাভাবিক std::move থেকে <utility>


10
যদি প্রকৃতপক্ষে খ হয় তবে অপরিজ্ঞাত আচরণ (যদি আপনি জানেন যে কখনই ঘটতে পারে না তবে এটি ঠিক আছে - তবে সাধারণ উদ্দেশ্য কোডে সচেতন হওয়া মূল্যবান)।
মার্টিন বোনার

1
@ মার্টিনবোনার এটি উল্লেখ করার জন্য ধন্যবাদ। সম্ভবত আমার পুরানো insertপথে ফিরে আসা উচিত যা নিরাপদ।
Deqing

15
আহ, অন্য স্ট্যান্ড :: পদক্ষেপ। আপনি প্রথমবার দেখতে পেয়ে বেশ বিভ্রান্তিকর।
xaxxon

1
এটা কি এস এর insert()সাথে আলাদা move_iterator? যদি তাই হয়, কিভাবে?
জিপিহিলো

1
std::moveআমরা এখানে কী বলছি সে সম্পর্কে আমি একটি নোট যুক্ত করেছি , কারণ বেশিরভাগ লোকেরা এই ওভারলোড জানেন না know আশা করি এটির উন্নতি হবে।
ওয়াইএসসি


24

আমি ইতিমধ্যে উল্লিখিত একটি পছন্দ:

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

তবে আপনি যদি সি ++ 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
@ আশু এডিএল কেবল তখন যুক্ত std::হবে যখন প্রকারটি aআসে std, যা জেনেরিক দিকটিকে পরাস্ত করে।
27:56 এ পোটোসওয়টার

ভাল যুক্তি. এই ক্ষেত্রে এটি একটি ভেক্টর তাই এটি যেভাবেই কাজ করবে তবে হ্যাঁ এটি আরও ভাল সমাধান।
আসু

স্টাডি :: শুরু () / শেষ () সংগ্রহের জন্য যুক্ত করা হয়েছিল (অ্যারেগুলির মতো) যা সদস্য ফাংশন হিসাবে তাদের নেই। তবে অ্যারেতেও একটি সন্নিবেশ () সদস্য ফাংশন নেই এবং প্রশ্নটি কল করে "" একটি সন্নিবেশ সহ কোনও সংগ্রহ আছে) (তবে) ছাড়াই () যা স্ট্যান্ড :: বিগ্রে () এর সাথে কাজ করে? "
জেমস কারান



9

একজন সাধারণ কর্মক্ষমতা বুস্ট CONCATENATE জন্য ভেক্টর আকার করা উচিত নয়। এবং বৃহত্তরটির সাথে ছোটটি একত্রীকরণ / sertোকান।

//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
ডেভিড স্টোন

আপনি দ্রুত অদলবদলও ব্যবহার করতে পারেন। @ ডেভিডস্টোন আমি এটি সম্পাদনা করেছি যাতে কনক্যাট অর্ডার পরিবর্তন হতে পারে। কোনও ভেক্টরের শুরুতে যুক্ত করা কি সম্ভব?
qwr

আপনি শুরুতে inোকাতে পারেন তবে এটি ধীর হবে। সত্যিকার অর্থে "কনটেনেটেট" করার জন্য, অর্ডারটি সাধারণত কার্যকর হয়, তাই আপনার যা করা দরকার তা হল।
ডেভিড স্টোন

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

আপনি যদি দৃ strong় ব্যতিক্রম গ্যারান্টিতে আগ্রহী হন (যখন অনুলিপি নির্মাণকারী একটি ব্যতিক্রম নিক্ষেপ করতে পারেন):

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;
    }
}

দৃ ve append_move় গ্যারান্টি সহ সাধারণভাবে কার্যকর করা যায় না যদি ভেক্টর এলিমেন্টের মুভ কনস্ট্রাক্টর নিক্ষেপ করতে পারেন (যা সম্ভাব্য নয় তবে এখনও)।


এটা v1.erase(...খুব নিক্ষেপ করা সম্ভব হয় না?
ক্লাস কঙ্কাল

insertইতিমধ্যে এটি পরিচালনা করে এছাড়াও, এই কলটি erasea এর সমতুল্য 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);

আর এতে [1,2,62] টি থাকবে


কেন এটিকে নিচে ভোট দেওয়া হয়েছে তা জানেন না। এটি করার সবচেয়ে কার্যকর উপায় নাও হতে পারে তবে এটি ভুল নয় এবং কার্যকর।
লিওরনেট

4

সি ++ 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)
ম্যাথিউ এইচ

4

সি ++ 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তবে এটি অন্যরকম কিছু করে: দুটি রেঞ্জকে নতুন পরিসরে একত্রিত করে বনাম অন্যটির শেষে একটি ভেক্টর সন্নিবেশ করানো। উত্তরে উল্লেখযোগ্য?
জেবি

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
যদিও এই কোড স্নিপেট সমস্যার সমাধান করতে পারে, এটি কেন বা কীভাবে প্রশ্নের উত্তর দেয় তা ব্যাখ্যা করে না। আপনার কোডটির জন্য একটি ব্যাখ্যা অন্তর্ভুক্ত করুন , কারণ এটি সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। ফ্ল্যাগার্স / পর্যালোচক: কোড-উত্তরগুলির জন্য যেমন এই, ডাউনভোট, মুছবেন না! (। নোট: এই উত্তরটি আসলে সহজ একটি ব্যাখ্যা করা যথেষ্ট হতে পারে, এবং এইভাবে downvotes অপ্রয়োজনীয় আপনি এখনও আরো NAA / VLQ পতাকা প্রতিরোধ একটি ব্যাখ্যা যোগ করতে চান পারে।)
স্কট মধ্যে Weldon

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এটি কিছু অপারেশন করে কেবল পুনরাবৃত্তি করা rate এই ক্ষেত্রে, হাস্যকর সহজ 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: ভেক্টর বি এর উপাদান যুক্ত / সন্নিবেশ করে ভেক্টর এ সংযুক্ত করুন

// 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
আপনার উত্তরটি কী যুক্ত করে যা ইতিমধ্যে অন্যান্য উত্তরে সরবরাহ করা হয়নি?
মাদুর

13
@ ম্যাট: বোল্ড অক্ষর।
marcv81

যদি আসল ভেক্টর (গুলি) এর পরে আর প্রয়োজন না হয় তবে এটি ব্যবহার করা ভাল std::move_iteratorso যাতে উপাদানগুলি অনুলিপি করার পরিবর্তে সরানো হয়। ( en.cppreferences.com/w/cpp/iterator/move_iterator দেখুন )।
tmlen

কী setcapacity? কী function: ?
এলএফ

@ এলএফ আমি মনে করি তিনি resizeপদ্ধতি সম্পর্কে কথা বলছেন ।
ম্যাথিউ এইচ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.