向順序容器新增元素

2022-04-12 01:02:42 字數 4397 閱讀 5336

除 array 外,所有標準庫容器都提供靈活的記憶體管理。在執行時可以動態新增或刪除元素來改變容器大小。表9.5 列出了向順序容器(非array)新增元素的操作。

當我們使用這些操作時,必須記得不同容器使用不同的策略來分配元素空間,而這些策略直接影響效能。

在乙個vector或 string 的尾部之外的任何位置,或是乙個deque的首尾之外的任何位置新增元素,都需要移動元素。

而且,向乙個vector或 string 新增元素可能引起整個物件儲存空間的重新分配。重新分配乙個物件的儲存空間需要分配新的記憶體,並將元素從舊的空間移動到新的空間中。

除 array 和 forward_list 之外,每個順序容器(包括 string型別)都支援 push_back。

例如,下面的迴圈每次讀取乙個 string 到word 中,然後追加到容器尾部:

string word;

while (cin >> word)

對 push_back 的呼叫在container尾部建立了乙個新的元素,將container的size增大了1。該元素的值為word的乙個拷貝。container 的型別可以是list、vector或 deque。

由於string是乙個字元容器,我們也可以用push_back在string末尾新增字元∶

void pluralize(size_t cnt, string &word)
當我們用乙個物件來初始化容器時,或將乙個物件插入到容器中時,實際上放入到容器中的是物件值的乙個拷貝,而不是物件本身。就像我們將乙個物件傳遞給非引用引數一樣,容器中的元素與提供值的物件之間沒有任何關聯。隨後對容器中元素的任何改變都不會影響到原始物件,反之亦然。

除了push_back,list、forward_list和deque容器還支援名為push_front的類似操作。此操作將元素插入到容器頭部:

listilist;

for (size_t ix = 0; ix != 4; ix++)

此迴圈將元素 0、1、2、3 新增到ilist 頭部。每個元素都插入到list的新的開始位置(new beginning)。即,當我們插入1時,它會被放置在0之前,2 被放置在1之前,依此類推。因此,在迴圈中以這種方式將元素新增到容器中,最終會形成逆序。在迴圈執行完畢後,ilist 儲存序列 3、2、1、0。

注意,deque 像 vector一樣提供了隨機訪問元素的能力,但它提供了vector所不支援的 push_front。deque 保證在容器首尾進行插入和刪除元素的操作都只花費常數時間。與 vector 一樣,在 deque 首尾之外的位置插入元素會很耗時。

push_back和push_front操作提供了一種方便地在順序容器尾部或頭部插入單個元素的方法。

insert 成員提供了更一般的新增功能,它允許我們在容器中任意位置插入 0個或多個元素。

vector、deque、list和string都支援insert成員。forward_list提供了特殊版本的 insert 成員。

每個 insert 函式都接受乙個迭代器作為其第乙個引數。迭代器指出了在容器中什麼位置放置新元素。它可以指向容器中任何位置,包括容器尾部之後的下乙個位置。由於迭代器可能指向容器尾部之後不存在的元素的位置,而且在容器開始位置插入元素是很有用的功能,所以insert 函式將元素插入到迭代器所指定的位置之前。例如,下面的語句

slist.insert(iter,"hello!");

// 將"hello!"新增到iter之前的位置將乙個值為"hello"的 string插入到iter指向的元素之前的位置。

雖然某些容器不支援 push_front 操作,但它們對於insert 操作並無類似的限制(插入開始位置)。因此我們可以將元素插入到容器的開始位置,而不必擔心容器是否支援 push_front:

vectorsvec;

listslist;

// 等價於呼叫slist.push_front("hello!");

slist.insert(slist.begin(), "hello!");

// vector不支援push_front,但我們可以插入到begin()之前

// 警告:插入到vector末尾之外的任何位置都很慢

svec.insert(svec.begin(), "hello!");

除了第乙個迭代器引數之外,insert 函式還可以接受更多的引數,這與容器建構函式類似。其中乙個版本接受乙個元素數目和乙個值,它將指定數量的元素新增到指定位置之前,這些元素都按給定值初始化:

svec.insert(svec.end(), 10, "anna");
這行**將10個元素插入到svec 的末尾,並將所有元素都初始化為string "anna"。

接受一對迭代器或乙個初始化列表的 insert 版本將給定範圍中的元素插入到指定位置之前∶

vectorv = ;

// 將v的最後兩個元素新增到slist開始的位置

slist.insert(slist.begin(), v.end() - 2, v.end());

slist.insert(slist.end(), );

// 執行時錯誤:迭代器表示要拷貝的範圍,不能指向與目的位置相同的元素

slist.insert(slist.begin(), slist.begin(), slist.end());

如果我們傳遞給 insert 一對迭代器,它們不能指向新增元素的目標容器。

在新標準下,接受元素個數或範圍的 insert 版本返回指向第乙個新加入元素的迭代器。(在舊版本的標準庫中,這些操作返回void。)如果範圍為空,不插入任何元素,insert操作會將第乙個引數返回。

通過使用insert的返回後,可以在容器中乙個特定的位置反覆地插入元素

listlst;

auto iter = lst.begin();

while (cin >> word)

在迴圈之前,我們將iter初始化為lst.begin()。

第一次呼叫 insert 會將我們剛剛讀入的 string插入到iter所指向的元素之前的位置。insert 返回的迭代器恰好指向這個新元素。我們將此迭代器賦予iter 並重複迴圈,讀取下乙個單詞。只要繼續有單詞讀入,每步 while 迴圈就會將乙個新元素插入到iter 之前,並將iter 改變為新加入元素的位置。此元素為(新的)首元素。因此,每步迴圈將乙個新元素插入到list 首元素之前的位置。

新標準引入了三個新成員——emplace_front、emplace 和 emplace_back,這些操作構造而不是拷貝元素。這些操作分別對應push_front、insert 和push_back,允許我們將元素放置在容器頭部、乙個指定位置之前或容器尾部。

當呼叫 push 或 insert 成員函式時,我們將元素型別的物件傳遞給它們,這些物件被拷貝到容器中。

而當我們呼叫乙個emplace 成員函式時,則是將引數傳遞給元素型別的建構函式。emplace 成員使用這些引數在容器管理的記憶體空間中直接構造元素。例如,假定c儲存 sales_data元素∶

// 在c的末尾構造乙個sale_data物件

// 使用三個引數的sales_data建構函式

c.emplace_back("978-0590353403", 25, 15.99);

// 錯誤

c.push_back("978-0590353403", 25, 15.99);

// 正確:建立乙個臨時的sales_data物件傳遞給push_back

c.push_back(sale_data("978-0590353403", 25, 15.99));

其中對emplace_back的呼叫和第二個 push_back呼叫都會建立新的 sales_data物件。在呼叫 emplace_back 時,會在容器管理的記憶體空間中直接建立物件。而呼叫 push_back 則會建立乙個區域性臨時物件,並將其壓入容器中。

emplace 函式的引數根據元素型別而變化,引數必須與元素型別的建構函式相匹配∶

// iter指向c中乙個元素,其中儲存了sales_data元素

c.emplace_back(); // 使用sales_data的預設建構函式

c.emplace(iter, "999-99999999"); // 使用sales_data(string)

// 使用sales_data的接受乙個isbn、乙個count和乙個price的建構函式

c.emplace_front("978-083846378", 25, 15.99);

容器新增元素操作

include include using namespace std intmain vector int vsz shuzu,shuzu 10 vector int iterator tdqa cout before delete for tdqa vsz.begin tdqa vsz.end ...

js向陣列裡新增元素

js中對於陣列的操作很常見,下面記錄一下js向陣列新增元素的方法。let myarray 11,22,33 console.log 原陣列 myarray myarray.push 44,55 console.log 用push在陣列後面插入元素 myarray myarray.unshift 66...

python 向列表裡面新增元素

python裡面的列表與其他語言的列表不同,雖然python是基於c語言開發的,但是它列表裡面的元素種類可以是混合的,它就是打了激素的陣列。1.列表的元素可以是相同的種類,也可以是不同種類的,如 name 小明 小紅 小華 小海 number 1 2,3 4,5 mix 小明 4 7.88 xiao...