我如何连接两个std::向量?


当前回答

这个解决方案可能有点复杂,但助推范围也有一些其他的好处。

#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结合起来只是在上面做一些运算。在本例中,有一个可笑的简单连接函数。

#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)这样的东西,这可能是合理的。

其他回答

c++ 17中有一个算法std::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;
}

如果您的目标只是为了只读目的而在值的范围内迭代,另一种替代方法是将两个向量围绕一个代理(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”实现以及优缺点。

我更喜欢前面提到的一个:

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

但是如果你使用c++ 11,有一个更通用的方法:

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

另外,这不是问题的一部分,但建议在追加之前使用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());
}

这个解决方案可能有点复杂,但助推范围也有一些其他的好处。

#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结合起来只是在上面做一些运算。在本例中,有一个可笑的简单连接函数。

#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)这样的东西,这可能是合理的。

你应该使用vector::insert

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