2008-11-24 106 views
30

我是第一次使用STL的C++程序員的C/Python程序員。C++用另一個向量擴展一個向量

在Python,與另一個列表延伸的列表使用.extend方法:

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

我目前使用這個算法方法在C延伸矢量++:

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

這是的規範的方法擴展向量,還是如果有一個更簡單的方法,我錯過了?

+0

[串聯兩個標準::載體]的可能的複製(http://stackoverflow.com/questions/201718/concatenating-two-stdvectors) – 2016-12-12 16:03:13

回答

45

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()); 
+0

我不認爲隨機訪問輸入迭代器有vector :: insert的專門化,所以如果性能很重要,請先保留()。 – 2008-11-24 05:04:29

+9

VC++ 9.0和GCC 4.3.2都在內部確定迭代器類別,因此您不需要保留。 – 2009-01-17 18:07:38

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

我所需要的extend函數的兩個不同的變體在C++ 14,其中對於向量中的每個元素的一個支持移動語義要追加。

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

有多種方法可以實現您的目標。

的std ::矢量::插入

載體可以通過在指定位置的元素之前插入新的元素,通過插入元件的數量有效地增加了容器的尺寸被延長。您可以按照以下方法之一進行操作。第二個版本使用C++ 11,它可以被認爲是更通用的答案,因爲b也可以是一個數組。

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

有時在使用中,使用std :: vector :: insert之前使用reserve函數是一種最佳做法。 std :: vector :: reserve函數將容器的容量增加到大於或等於new_cap的值。如果new_cap大於當前容量(),則分配新的存儲空間,否則該方法將不執行任何操作。

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

使用保留功能不是必需的,但可能是明智的。如果你反覆插入一個你知道最終尺寸的矢量,並且這個尺寸很大,最好使用保留。否則,最好讓STL根據需要增長你的向量。

的std ::複製

的std ::複製是你可以考慮實現目標的第二個選項。此函數將範圍(第一個,最後一個)中的元素複製到從結果開始的範圍內。

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

但使用的std ::副本比使用std ::載體::插入()慢一些,因爲它沒有前手(標準::複製()不能保留足夠的空間有權訪問矢量本身,只能訪問具有的迭代器),而作爲成員函數的std :: vector :: insert()可以。由於std :: copy的確比使用std :: vector :: insert慢。大多數人在使用std :: copy時不知道這種情況。

的boost ::的push_back

,你可以考慮第三種選擇是採用升壓轉換器的的push_back功能。

boost::push_back(a, b); 
1

使用std::vector::insert;

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

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


Convienent碼發生器以節省寶貴秒:

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