加入两个std ::向量

发布于 2025-01-19 04:03:14 字数 44 浏览 4 评论 0 原文

如何串联两个 std :: vector s?

How do I concatenate two std::vectors?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(29

强者自强 2025-01-26 04:03:14
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
忘年祭陌 2025-01-26 04:03:14

如果您使用的是C ++ 11,并希望移动元素而不是仅复制它们,则可以使用 std :: move_iterator 以及insert(或复制):

#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的新元素。

If you are using C++11, and wish to move the elements rather than merely copying them, you can use std::move_iterator along with insert (or copy):

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

This will not be more efficient for the example with ints, since moving them is no more efficient than copying them, but for a data structure with optimized moves, it can avoid copying unnecessary state:

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

After the move, src's element is left in an undefined but safe-to-destruct state, and its former elements were transfered directly to dest's new element at the end.

回忆躺在深渊里 2025-01-26 04:03:14

我会使用插入函数,类似:

vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());

I would use the insert function, something like:

vector<int> a, b;
//fill with data
b.insert(b.end(), a.begin(), a.end());
源来凯始玺欢你 2025-01-26 04:03:14

或者您可以使用:

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

如果两个向量不包含完全相同类型的事物,则此模式很有用,因为您可以使用某些东西而不是 std :: back_inserter 将一种类型转换为另一种类型。

Or you could use:

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

This pattern is useful if the two vectors don't contain exactly the same type of thing, because you can use something instead of std::back_inserter to convert from one type to the other.

仲春光 2025-01-26 04:03:14

使用C ++ 11,我希望跟随Vector B附加到A:

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

a b 不会重叠, b is不再使用了。


这是 std :: move 来自 &lt; algorithm&gt; ,而不是常规 std ::移动 来自&lt; codilition&gt;

With C++11, I'd prefer following to append vector b to a:

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

when a and b are not overlapped, and b is not going to be used anymore.


This is std::move from <algorithm>, not the usual std::move from <utility>.

抚你发端 2025-01-26 04:03:14
std::vector<int> first;
std::vector<int> second;

first.insert(first.end(), second.begin(), second.end());
std::vector<int> first;
std::vector<int> second;

first.insert(first.end(), second.begin(), second.end());
只是在用心讲痛 2025-01-26 04:03:14

使用 range v3 ,您可能有一个 lazy lazy convatenation:

ranges::view::concat(v1, v2)

demo

With range v3, you may have a lazy concatenation:

ranges::view::concat(v1, v2)

Demo.

邮友 2025-01-26 04:03:14

我更喜欢已经提到的:

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

但是,如果您使用C ++ 11,还有一种通用方法:

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

另外,不是问题的一部分,但是建议使用 储备>储备 在附加以提高性能之前。而且,如果您将向量与自身连接,而没有保留它会失败,则您始终应储备


因此,基本上您需要的是:

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

I prefer one that is already mentioned:

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

But if you use C++11, there is one more generic way:

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

Also, not part of a question, but it is advisable to use reserve before appending for better performance. And if you are concatenating vector with itself, without reserving it fails, so you always should reserve.


So basically what you need:

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());
}
远昼 2025-01-26 04:03:14

A 一般性能提升连续的是检查向量的大小。并将较小的合并与较大的合并。

//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());
}

A general performance boost for concatenate is to check the size of the vectors. And merge/insert the smaller one with the larger one.

//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());
}
痴情 2025-01-26 04:03:14

有一个算法 std::merge 来自 < strong>C++17,当输入向量排序时非常容易使用,

下面是示例:

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

There is an algorithm std::merge from C++17, which is very easy to use when the input vectors are sorted,

Below is the example:

#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;
}
攒一口袋星星 2025-01-26 04:03:14

在C ++ 23中,可以使用其成员函数 append_range (如果存在)将范围连接到标准容器。

因此,可以通过以下方式执行两个 std :: vector 对象的串联:

vec1.append_range(vec2);

In C++23, it is possible to concatenate a range to a standard container using its member function append_range, if present.

Thus, the concatenation of two std::vector objects can be performed in following way:

vec1.append_range(vec2);
野侃 2025-01-26 04:03:14

如果您希望能够简洁地连接向量,您可以重载 += 运算符。

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;

If you want to be able to concatenate vectors concisely, you could overload the += operator.

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

Then you can call it like this:

vector1 += vector2;
强者自强 2025-01-26 04:03:14

使用C ++ 20,您可以使用范围来摆脱begin()和end()。

#include <ranges>

std::ranges::copy(vec2, std::back_inserter(vec1));

或者,如果您想移动元素:

std::ranges::move(vec2, std::back_inserter(vec1));

Using C++20 you can get rid of begin() and end() with ranges.

#include <ranges>

std::ranges::copy(vec2, std::back_inserter(vec1));

or if you want to move elements:

std::ranges::move(vec2, std::back_inserter(vec1));
温柔戏命师 2025-01-26 04:03:14

您应该使用 vector :: insert

v1.insert(v1.end(), v2.begin(), v2.end());

You should use vector::insert

v1.insert(v1.end(), v2.begin(), v2.end());
红墙和绿瓦 2025-01-26 04:03:14

如果您对强异常保证感兴趣(当复制构造函数可以抛出异常时):

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 (这不太可能,但仍然)。

If you are interested in strong exception guarantee (when copy constructor can throw an exception):

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

Similar append_move with strong guarantee can't be implemented in general if vector element's move constructor can throw (which is unlikely but still).

空城之時有危險 2025-01-26 04:03:14

如果您的目标仅仅是为了迭代仅阅读目的的值范围,那么一种替代方法是将两个向量围绕代理(O(1))而不是复制它们(O(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/5555838758/2379625 有关更多详细信息,包括'vecproxy as as as a veecproxy'simentation as as as versimentation as as veecproxy'以及Pros&amp;缺点。

If your goal is simply to iterate over the range of values for read-only purposes, an alternative is to wrap both vectors around a proxy (O(1)) instead of copying them (O(n)), so they are promptly seen as a single, contiguous one.

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

Refer to https://stackoverflow.com/a/55838758/2379625 for more details, including the 'VecProxy' implementation as well as pros & cons.

↙厌世 2025-01-26 04:03:14

将此添加到标题文件中:

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]

Add this one to your header file:

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

and use it this way:

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 will contain [1,2,62]

痴梦一场 2025-01-26 04:03:14

这是使用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);
}

请注意,这与 附加到 vector

Here's a general purpose solution using C++11 move semantics:

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

Note how this differs from appending to a vector.

ㄟ。诗瑗 2025-01-26 04:03:14
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {11, 12, 13, 14, 15};
copy(v2.begin(), v2.end(), back_inserter(v1));
吲‖鸣 2025-01-26 04:03:14

您可以为 +操作员准备自己的模板:

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

You can prepare your own template for + operator:

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

Next thing - just use +:

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

This example gives output:

1 2 3 4 5 6 7 8
双手揣兜 2025-01-26 04:03:14

我已经实现了这个函数,它连接任意数量的容器,从右值引用移动并以其他方式复制

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

I've implemented this function which concatenates any number of containers, moving from rvalue-references and copying otherwise

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;
}
黯然#的苍凉 2025-01-26 04:03:14

对于提供 push_back 的容器(字符串,向量,deque,...):

std :: copy(std :: begin(input),std :: end(Intput),std: :back_inserter(output))

提供提供 insert (映射,设置)的容器:

std :: copy(std :: begin(input),std :: end(end)输入),std :: inserster(output,output.end()))

For containers which offer push_back (string, vector, deque, ...):

std::copy(std::begin(input), std::end(input), std::back_inserter(output))

and

for containers which offer insert (maps, sets):

std::copy(std::begin(input), std::end(input), std::inserter(output, output.end()))

空‖城人不在 2025-01-26 04:03:14

该解决方案可能有点复杂,但是 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;
}

通常,意图是将vector a b 组合起来,只是迭代它进行一些操作。在这种情况下,有一个荒谬的简单加入函数。

#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),这是合理的。

This solution might be a bit complicated, but boost-range has also some other nice things to offer.

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

Often ones intention is to combine vector a and b just iterate over it doing some operation. In this case, there is the ridiculous simple join function.

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

For large vectors this might be an advantage, as there is no copying. It can be also used for copying an generalizes easily to more than one container.

For some reason there is nothing like boost::join(a,b,c), which could be reasonable.

凉栀 2025-01-26 04:03:14

如果您要寻找的是一种在创建后将向量附加到另一个的方法,则 vector :: insert 是您最好的选择,例如:

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

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

可悲的是:可悲的是,无法构建 const vector&lt; int&gt; ,如上所述,您必须构造然后插入


如果您实际寻找的是一个容器,可以保留这两个 vector&lt; int s的串联,则可能有一些更好的东西,如果

  1. 您的 vector 包含原始图,
  2. 您所包含的原始尺寸为32位或更小的尺寸,
  3. 您想要一个 const 容器,

如果以上都是正确的,我建议使用 basic_string 谁是 char_type 匹配您<<代码>向量。您应该包括a static_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/355558008/2642059

有关此代码的实时示例,您可以在此处查看: http://ideone.com/7iww3i

If what you're looking for is a way to append a vector to another after creation, vector::insert is your best bet, as has been answered several times, for example:

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

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

Sadly there's no way to construct a const vector<int>, as above you must construct and then insert.


If what you're actually looking for is a container to hold the concatenation of these two vector<int>s, there may be something better available to you, if:

  1. Your vector contains primitives
  2. Your contained primitives are of size 32-bit or smaller
  3. You want a const container

If the above are all true, I'd suggest using the basic_string who's char_type matches the size of the primitive contained in your vector. You should include a static_assert in your code to validate these sizes stay consistent:

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

With this holding true you can just do:

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

For more information on the differences between string and vector you can look here: https://stackoverflow.com/a/35558008/2642059

For a live example of this code you can look here: http://ideone.com/7Iww3I

孤单情人 2025-01-26 04:03:14

您可以使用用于多态性类型的模板使用预先实现的STL算法进行操作。

#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()方法),则可以清除第二个矢量。

You can do it with pre-implemented STL algorithms using a template for a polymorphic type use.

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

You can clear the second vector if you don't want to use it further (clear() method).

草莓酥 2025-01-26 04:03:14

我尝试在 C++17 中解决此任务,而不使用 rangesV3 库。阅读本主题中的一些帖子后,我提出了以下解决方案:

namespace algorithms
{
/*!
 * \brief Wraps incoming element and move/or copy the elements from one to another.
 * \example return (wrapped_plus(container) + ...).value
 */
template <class T>
struct wrapped_plus {
    using value_type = T;

    value_type value;

    wrapped_plus(value_type&& in) : value(std::move(in)) {}
    wrapped_plus(const value_type& in) : value(in) {}

    wrapped_plus operator+(const wrapped_plus& in)
    {
        std::copy(std::begin(in.value), std::end(in.value), std::back_inserter(value));
        return *this;
    }

    wrapped_plus operator+(wrapped_plus&& in)
    {
        std::move(std::make_move_iterator(std::begin(in.value)), std::make_move_iterator(std::end(in.value)), std::back_inserter(value));
        return *this;
    }
};

/*!
 * \brief Merge 2 or more STL containers with same type.
 * \example merge(container,container,container)
 */
template <typename... Containers>
static inline auto merge(Containers&&... c)
{
    return (wrapped_plus(c) + ...).value;
}
}  // namespace algorithms

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

    auto result =  algorithms::merge(dest,src);

    return 0;
}

完整示例

I tried to solve this task in C++17 without using the rangesV3 library. After reading some posts in this topic, I made this solution:

namespace algorithms
{
/*!
 * \brief Wraps incoming element and move/or copy the elements from one to another.
 * \example return (wrapped_plus(container) + ...).value
 */
template <class T>
struct wrapped_plus {
    using value_type = T;

    value_type value;

    wrapped_plus(value_type&& in) : value(std::move(in)) {}
    wrapped_plus(const value_type& in) : value(in) {}

    wrapped_plus operator+(const wrapped_plus& in)
    {
        std::copy(std::begin(in.value), std::end(in.value), std::back_inserter(value));
        return *this;
    }

    wrapped_plus operator+(wrapped_plus&& in)
    {
        std::move(std::make_move_iterator(std::begin(in.value)), std::make_move_iterator(std::end(in.value)), std::back_inserter(value));
        return *this;
    }
};

/*!
 * \brief Merge 2 or more STL containers with same type.
 * \example merge(container,container,container)
 */
template <typename... Containers>
static inline auto merge(Containers&&... c)
{
    return (wrapped_plus(c) + ...).value;
}
}  // namespace algorithms

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

    auto result =  algorithms::merge(dest,src);

    return 0;
}

COMPLETE EXAMPLE

岁月如刀 2025-01-26 04:03:14

将两个 std::vector-sfor 循环连接到一个 std::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(int i = 0; i < v1.size(); i++) //for loop 1
    {
         suma.push_back(v1[i]);
    }

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

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

Concatenate two std::vector-s with for loop in one std::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(int i = 0; i < v1.size(); i++) //for loop 1
    {
         suma.push_back(v1[i]);
    }

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

    for(int i = 0; i < suma.size(); i++) //for loop 3-output
    {
         std::cout << suma[i];
    }
我的鱼塘能养鲲 2025-01-26 04:03:14

老实说,您可以通过从两个向量到另一个矢量的复制元素加快两个向量,或者仅将两个向量之一附加到两个矢量中!。这取决于您的目标。

方法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());

To be honest, you could fast concatenate two vectors by copy elements from two vectors into the other one or just only append one of two vectors!. It depends on your aim.

Method 1: Assign new vector with its size is the sum of two original vectors' size.

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

Method 2: Append vector A by adding/inserting elements of vector B.

// 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());
自由范儿 2025-01-26 04:03:14

尝试创建两个向量并将第二个向量添加到第一个向量,
代码:

std::vector<int> v1{1,2,3};
std::vector<int> v2{4,5};

for(int i = 0; i<v2.size();i++)
{
     v1.push_back(v2[i]);
}

v1:1,2,3。

描述:

当 i int 不是 v2 大小时,推回 v1 向量中的索引 i 的元素。

Try, create two vectors and add second vector to first vector,
code:

std::vector<int> v1{1,2,3};
std::vector<int> v2{4,5};

for(int i = 0; i<v2.size();i++)
{
     v1.push_back(v2[i]);
}

v1:1,2,3.

Description:

While i int not v2 size, push back element , index i in v1 vector.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文