C++ 用另一个向量扩展一个向量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/313432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:33:48  来源:igfitidea点击:

C++ extend a vector with another vector

c++vector

提问by cdleary

I'm a C/Python programmer in C++ land working with the STL for the first time.

我是 C++ 领域的 C/Python 程序员,第一次使用 STL。

In Python, extending a list with another list uses the .extendmethod:

在 Python 中,使用另一个列表扩展列表使用以下.extend方法:

>>> v = [1, 2, 3]
>>> v_prime = [4, 5, 6]
>>> v.extend(v_prime)
>>> print(v)
[1, 2, 3, 4, 5, 6]

I currently use this algorithmic approach to extend vectors in C++:

我目前使用这种算法方法来扩展 C++ 中的向量:

v.resize(v.size() + v_prime.size());
copy(v_prime.begin(), v_prime.end(), v.rbegin());

Is this the canonical way of extending vectors, or if there is a simpler way that I'm missing?

这是扩展向量的规范方法,还是我缺少的更简单的方法?

回答by Dmitry Khalatov

From here

这里

// reserve() is optional - just to improve performance
v.reserve(v.size() + distance(v_prime.begin(),v_prime.end()));
v.insert(v.end(),v_prime.begin(),v_prime.end());

回答by CTT

copy(v_prime.begin(), v_prime.end(), back_inserter(v));

回答by Tharindu Kumara

There are multiple ways to achieve your target.

有多种方法可以实现您的目标。

std::vector::insert

标准::向量::插入

The vector can be extended by inserting new elements before the element at the specified position, effectively increasing the container size by the number of elements inserted. You can follow one of below approaches. The second version uses C++11 and it can be considered as a more generic answer, as b could also be an array.

可以通过在指定位置的元素之前插入新元素来扩展向量,通过插入的元素数量有效地增加容器大小。您可以遵循以下方法之一。第二个版本使用 C++11,它可以被认为是一个更通用的答案,因为 b 也可以是一个数组。

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

Sometimes in usage it is a best practice to use reserve function before using std::vector::insert. std::vector::reservefunction increases the capacity of the container to a value that's greater or equal to new_cap. If new_cap is greater than the current capacity(), new storage is allocated, otherwise the method does nothing.

有时在使用中最好在使用 std::vector::insert 之前使用保留函数。std::vector::reserve函数将容器的容量增加到大于或等于 new_cap 的值。如果 new_cap 大于当前容量(),则分配新的存储,否则该方法不执行任何操作。

a.reserve(a.size() + distance(b.begin(), b.end()));

Use of reserve function is not required but may be advisable. And it is best practive to use reserve if you are repeatedly inserting into a vector for which you know the final size, and that size is large. Otherwise, it is better to let the STL grow your vector as needed.

使用保留功能不是必需的,但可能是可取的。如果您重复插入一个已知最终大小的向量,并且该大小很大,那么最好使用保留。否则,最好让 STL 根据需要增长您的载体。

std::copy

标准::复制

std::copy is the second option that you can consider to achieve your target. This function copies the elements in the range (first,last) into the range beginning at result.

std::copy 是您可以考虑实现目标的第二个选项。此函数将范围(第一个,最后一个)中的元素复制到从结果开始的范围中。

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

However use of std::copy is slower than use of std::vector::insert(), because std::copy() can't reserve enough space before-hand (it doesn't have access to the vector itself, only to an iterator which has), while std::vector::insert(), being a member function, can. Due to that std::copy is indeed slower than using std::vector::insert. Most of the people, over use std::copy without knowing this scenario.

然而,使用 std::copy 比使用 std::vector::insert() 慢,因为 std::copy() 不能预先保留足够的空间(它无法访问向量本身,仅适用于具有) 的迭代器,而作为成员函数的 std::vector::insert() 可以。由于 std::copy 确实比使用 std::vector::insert 慢。大多数人在不知道这种情况的情况下过度使用 std::copy 。

boost::push_back

boost::push_back

The third option that you can consider is the use of boost's push_backfunction.

您可以考虑的第三个选项是使用 boost 的push_back函数。

boost::push_back(a, b);

回答by TheJJ

I needed two different variants of the extendfunction in C++14, where one supported move semantics for each element of the vector to be appended.

我需要extendC++14 中函数的两个不同变体,其中一个支持要附加的向量的每个元素的移动语义。

vecis your v, and extis your v_prime.

vec是你的vext也是你的v_prime

/**
 * Extend a vector with elements, without destroying source one.
 */
template<typename T>
void vector_extend(std::vector<T> &vec, const std::vector<T> &ext) {
    vec.reserve(vec.size() + ext.size());
    vec.insert(std::end(vec), std::begin(ext), std::end(ext));
}

/**
 * Extend a vector with elements with move semantics.
 */
template<typename T>
void vector_extend(std::vector<T> &vec, std::vector<T> &&ext) {
    if (vec.empty()) {
        vec = std::move(ext);
    }
    else {
        vec.reserve(vec.size() + ext.size());
        std::move(std::begin(ext), std::end(ext), std::back_inserter(vec));
        ext.clear();
    }
}

回答by no?????z???

Using std::vector::insert;

使用std::vector::insert;

A.reserve(A.size() + B.size());
A.insert(A.end(), B.begin(), B.end());

reserve()is optional, but using it helps to improve performance.

reserve()是可选的,但使用它有助于提高性能。



Convienent code generator to save precious seconds:

方便的代码生成器以节省宝贵的时间:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css"><script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script><script src="https://cdn.jsdelivr.net/clipboard.js/1.6.0/clipboard.min.js"></script><script>function generateCode(){codeTemplate="{0}.reserve({0}.size() + {1}.size()); \n{0}.insert({0}.end(), {1}.begin(), {1}.end());",first=document.getElementById("1").value,second=document.getElementById("2").value,""==first&&(first="A"),""==second&&(second="B"),document.getElementById("c").innerHTML=String.format(codeTemplate,first,second)}String.format||(String.format=function(a){var b=Array.prototype.slice.call(arguments,1);return a.replace(/{(\d+)}/g,function(a,c){return"undefined"!=typeof b[c]?b[c]:a})});</script><div class="A" style="margin:3% 10% 1% 10%;"><label for="1">First vector name:</label><input id="1"/><br/><label for="1">Second vector name:</label><input id="2"/><div class="D"><a class="waves-effect waves-light btn red col" onclick="generateCode();" style="margin:0 0 4% 0;">Generate Code</a></div><textarea id="c" onclick="this.select()" style="border:none;height:auto;overflow: hidden;font-family:Consolas,Monaco;">A.reserve(A.size() + B.size());&#13;&#10;A.insert(A.end(), B.begin(), B.end());</textarea></div>