846

2 つの s を連結するにはどうすればよいstd::vectorですか?

4

26 に答える 26

910
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
于 2008-10-14T15:48:28.397 に答える
263

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

これは、int を使用した例では効率的ではありません。移動はコピーよりも効率的ではないためです。ただし、移動が最適化されたデータ構造では、不要な状態のコピーを回避できます。

#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 の要素は未定義ですが安全に破壊できる状態のままになり、最後に以前の要素が dest の新しい要素に直接転送されました。

于 2014-02-23T18:11:47.363 に答える
176

次のような挿入関数を使用します。

vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());
于 2008-10-14T15:48:15.510 に答える
84

または、次を使用できます。

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

このパターンは、2つのベクトルにまったく同じタイプのものが含まれていない場合に役立ちます。これはstd::back_inserter、あるタイプから別のタイプに変換する代わりに、何かを使用できるためです。

于 2008-10-14T16:20:34.977 に答える
75

C++ 11 では、ベクトル b を a に追加することをお勧めします。

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

whenabは重複しておらず、b今後使用されません。


これはstd::moveから<algorithm>のもので、通常の std::moveからではありません<utility>

于 2015-06-12T07:53:19.197 に答える
42
std::vector<int> first;
std::vector<int> second;

first.insert(first.end(), second.begin(), second.end());
于 2008-10-14T15:48:37.897 に答える
33

私はすでに言及されているものを好みます:

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

しかし、C++11 を使用する場合は、もう 1 つの一般的な方法があります。

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());
}
于 2016-06-10T09:27:16.817 に答える
15

ベクトルを簡潔に連結できるようにしたい場合は、+=演算子をオーバーロードできます。

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;
于 2019-06-26T22:15:35.693 に答える
9

vector::insertを使用する必要があります

v1.insert(v1.end(), v2.begin(), v2.end());
于 2017-08-08T09:38:02.603 に答える
7

読み取り専用の目的で値の範囲を単純に反復することが目的の場合、代わりに、両方のベクトルをコピー (O(n)) する代わりに、プロキシ (O(1)) でラップすることで、すぐに表示されるようにします。単一の連続したものとして。

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

「VecProxy」の実装や長所と短所などの詳細については、https: //stackoverflow.com/a/55838758/2379625 を参照してください。

于 2019-10-21T19:21:30.530 に答える
6

これをヘッダー ファイルに追加します。

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] が含まれます

于 2015-11-11T11:32:45.380 に答える
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
于 2018-07-31T12:43:53.720 に答える
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));
于 2016-12-16T11:57:35.440 に答える
0

探しているものが、作成後にベクターを別のベクターに追加する方法である場合は、次のようにvector::insert何度か回答されているように、最善の策です。

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

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

悲しいことに、 a を構築する方法はconst vector<int>ありません。上記のように、構築してからinsert.


実際に探しているのがこれら 2 つvector<int>の s の連結を保持するコンテナーである場合は、次の場合により適切なものが利用できる可能性があります。

  1. プリミティブvectorが含まれています
  2. 含まれているプリミティブのサイズは 32 ビット以下です
  3. constコンテナが欲しい

上記がすべて当てはまる場合は、に含まれるプリミティブのサイズに一致するbasic_stringwhoを使用することをお勧めします。これらのサイズが一貫していることを検証するには、コードに を含める必要があります。char_typevectorstatic_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を参照してください。

于 2016-02-22T18:53:45.860 に答える
-5

正直なところ、2 つのベクトルの要素を別のベクトルにコピーするか、2 つのベクトルの 1 つだけを追加することで、2 つのベクトルを高速に連結できます。それはあなたの目的次第です。

方法 1:サイズが 2 つの元のベクトルのサイズの合計である新しいベクトルを割り当てます。

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());
于 2016-12-27T06:39:21.147 に答える