日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++中vector的使用

發布時間:2023/11/27 生活经验 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中vector的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

向量std::vector是一種對象實體,能夠容納許多各種類型相同的元素,包括用戶自定義的類,因此又被稱為序列容器。與string相同,vector同屬于STL(Standard Template Library)中的一種自定義的數據類型,可以廣義上認為是數組的增強版,相當于一個動態數組。

???????? 在使用它時,需要包含頭文件vector: #include <vector>

???????? vector是一個類模板,不是一種數據類型:

template<class T, class Alloc = allocator<T> > class vector;
?vector可以存放任何類型的對象(但必須是同一類對象)。vector對象可以在運行時高效地添加元素。vector中元素是連續存儲的,所以除了能夠通過迭代器訪問外,還可以通過常規的指針偏移量訪問元素。換句話說,可以將指向vector元素的指針傳入以指向數組元素的指針作為參數的函數。

???????? vector會在需要時自動調整所占內存的大小。與對應的靜態數組相比,vector 所占的內存通常要更多,因為它還分配了額外的內存以應對將來可能的擴張。于是,vector 就不必在每次插入元素時都重新分配一次內存了,除非這塊預留的內存用盡。已分配內存的總大小可以通過 capacity() 函數查詢。所占的額外的內存可以通過調用 shrink_to_fit()(c++11) 返還給系統。

從性能方面考慮,內存重分配操作的代價通常很大。如果事先知道元素個數,可以使用 reserve() 函數消除重新分配操作。

???????? vector值初始化:

(1)、如果沒有指定元素初始化,標準庫自行提供一個初始化值進行初始化;

(2)、如果保存的是含有構造函數的類類型的元素,標準庫使用該類型的構造函數初始化;

(3)、如果保存的是沒有構造函數的類類型的元素,標準庫產生一個帶初始值的對象,使用這個對象進行值初始化。

vector容器內存放的所有對象都是經過初始化的。如果沒有指定存儲對象的初始值,那么對于內置類型將用0初始化,對于類類型將調用其默認構造函數進行初始化(如果有其它構造函數而沒有默認構造函數,那么此時必須提供元素初始值才能放入容器中)。

一個容器就是一些特定類型對象的集合。順序容器(sequential container)為程序員提供了控制元素存儲和訪問順序的能力。這種順序不依賴于元素的值,而是與元素加入容器時的位置相對應。

???????? 標準庫中的順序容器包括:

???????? (1)、vector:可變大小數組。支持快速隨機訪問。在尾部之外的位置插入或刪除元素可能很慢。

???????? (2)、deque:雙端隊列。支持快速隨機訪問。在頭尾位置插入/刪除速度很快。

???????? (3)、list:雙向鏈表。只支持雙向順序訪問。在list中任何位置進行插入/刪除操作速度都很快。

???????? (4)、forward_list:單向鏈表。只支持單向順序訪問。在鏈表任何位置進行插入/刪除操作速度都很快。

???????? (5)、array:固定大小數組。支持快速隨機訪問。不能添加或刪除元素。

???????? (6)、string:與vector相似的容器,但專門用于保存字符。隨機訪問快。在尾部插入/刪除速度快。

???????? 除了固定大小的array外,其它容器都提供高效、靈活的內存管理。我們可以添加和刪除元素,擴張和收縮容器的大小。容器保存元素的策略對容器操作的效率有著固定的,有時是重大的影響。在某些情況下,存儲策略還會影響特定容器是否支持特定操作。

???????? 例如,string和vector將元素保存在連續的內存空間中。由于元素是連續存儲的,由元素的下標來計算其地址是非常快速的。但是,在這兩種容器的中間位置添加或刪除元素就會非常耗時:在一次插入或刪除操作后,需要移動插入/刪除位置之后的所有元素,來保持連續存儲。而且,添加一個元素有時可能還需要分配額外的存儲空間。在這種情況下,每個元素都必須移動到新的存儲空間中。

???????? list和forward_list兩個容器的設計目的是令容器任何位置的添加和刪除操作都很快速。作為代價,這兩個容器不支持元素的隨機訪問:為了訪問一個元素,我們只能遍歷整個容器。而且,與vector、deque和array相比,這兩個容器的額外內存開銷也很大。

???????? deque是一個更為復雜的數據結構。與string和vector類似,deque支持快速的隨機訪問。與string和vector一樣,在deque的中間位置添加或刪除元素的代價(可能)很高。但是,在deque的兩端添加或刪除元素都是很快的,與list或forward_list添加刪除元素的速度相當。

???????? forward_list和array是新C++標準增加的類型。與內置數組相比,array是一個種更安全、更容易使用的數組類型。與內置數組類似,array對象的大小是固定的。因此,array不支持添加和刪除元素以及改變容器大小的操作。forward_list的設計目標是達到與最好的手寫的單向鏈表數據結構相當的性能。因此,forward_list沒有size操作,因為保存或計算其大小就會比手寫鏈表多出額外的開銷。對其他容器而言,size保證是一個快速的常量時間的操作。

???????? 通常,使用vector是最好的選擇,除法你有很好的理由選擇其他容器。

???????? 以下是一些選擇容器的基本原則:

???????? (1)、除法你有很好的理由選擇其他容器,否則應該使用vector;

???????? (2)、如果你的程序有很多小的元素,且空間的額外開銷很重要,則不要使用list或forward_list;

???????? (3)、如果程序要求隨機訪問元素,應使用vector或deque;

???????? (4)、如果程序要求在容器的中間插入或刪除元素,應使用list或forward_list;

(5)、如果程序需要在頭尾位置插入或刪除元素,但不會在中間位置進行插入或刪除操作,則使用deque;

(6)、如果程序只有在讀取輸入時才需要在容器中間位置插入元素,隨后需要隨機訪問元素,則:首先,確定是否真的需要在容器中間位置添加元素。當處理輸入數據時,通常可以很容器地向vector追加數據,然后再調用標準庫的sort函數來重排容器中的元素,從而避免在中間位置添加元素。如果必須在中間位置插入元素,考慮在輸入階段使用list,一旦輸入完成,將list中的內容拷貝到一個vector中。

如果你不確定應該使用哪種容器,那么可以在程序中只使用vector和list公共的操作:使用迭代器,不使用下標操作,避免隨機訪問。這樣,在必要時選擇使用vector或list都很方便。

一般來說,每個容器都定義在一個頭文件中,文件名與類型名相同。即,deque定義在頭文件deque中,list定義在頭文件list中,以此類推。容器均定義為模板類。

順序容器幾乎可以保存任意類型的元素。特別是,我們可以定義一個容器,其元素的類型是另一個容器。這種容器的定義與任何其他容器類型完全一樣:在尖括號中指定元素類型(此種情況下,是另一種容器類型)。

下面是測試代碼vector.cpp:

#include <vector>
#include <iostream>
#include <assert.h>#include "vector.hpp"int test_vector_init()
{std::vector<int> a; // 聲明一個int型向量a,size為0std::vector<int> b(10); // 聲明一個初始size為10的向量std::vector<int> c(10, 1); // 聲明一個初始size為10且初始值都為1的向量std::vector<int> d(b); // 聲明并用向量b初始化向量dstd::vector<int> e(c.begin(), c.begin() + 3); // 將c向量中從第0個到第2個(共3個)作為向量e的初始值,size為3int n[] = { 1, 2, 3, 4, 5 };std::vector<int> f(n, n + 5); // 將數組n的前5個元素作為向量f的初值,size為5std::vector<int> g(&n[1], &n[4]); // 將n[1] - n[4]范圍內的元素作為向量g的初值,size為3std::vector<std::string> v(5, "hello");std::vector<std::string> v2(v.begin(), v.end());assert(v == v2);assert(v.begin() + v.size() == v.end());assert(v.end() - v.size() == v.begin());std::vector<int> array{ 9, 7, 5, 3, 1 };std::cout << "array size: "<< array.size() << std::endl; // 5return 0;
}int test_vector_access()
{int n[10];for (int i = 0; i < 10; i++) {n[i] = i;}std::vector<int> a(n, n + 10);// 對其中部分元素進行輸入std::cin >> a[2];std::cin >> a[5];std::cin >> a[6];// 輸出for (int i = 0; i < a.size(); i++) {std::cout << a[i] << " ";}std::cout << std::endl;// 使用遍歷器(又稱迭代器)進行輸出// vector類的迭代器除了支持通用的前綴自增運算符外,還支持算術運算:it + n、it - n、it2 - it1std::vector<int>::iterator t;for (t = a.begin(); t != a.end(); t++) {std::cout << *t << " ";}std::cout << std::endl;for (std::vector<int>::const_iterator p = a.begin(); p != a.end(); p++) {std::cout << *p << " ";}std::cout << std::endl;size_t i = 0;int* x = a.data(); //返回指向內存中數組第一個元素的指針*x = -111;std::cout << "a[0]: " << a[0] << std::endl; // -111return 0;
}int test_vector_operation()
{int n[10], m[15];for (int i = 0; i < 10; i++) {n[i] = i;m[i] = i + 20;}std::vector<int> a(n, n + 10);std::vector<int> b(m, m + 15);std::vector<int> x;x = a; // 賦值std::cout << "x size: "<<a.size() << std::endl; // 獲取向量中的元素個數, 10std::cout << "x capacity: " << x.capacity() << std::endl; // 返回當前存儲空間能夠容納的元素數,容器x能夠存儲的元素個數,10 (x.capacity() >= x.size())std::cout << "x max size: " << x.max_size() << std::endl; // 容器x能容納的最大元素個數, 4611686018427387903x.reserve(15); // 預留存儲空間,確保x.capacity() >= 15std::cout << "x capacity after reserve: " << x.capacity() << std::endl; // 15x.shrink_to_fit();x.resize(5); // 改變容器中可存儲元素的個數,確保返回后,有x.size() == 5, 如果之前x.size() < 5, 那么用默認值補全std::cout << "x size after resize: " << x.size() << std::endl; // 5std::vector<int>::reference ref1 = b.front(); // 返回容器中第一個元素的引用(容器必須非空), 20std::vector<int>::reference ref2 = x.back(); // 返回容器中最后一個元素的引用(容器必須非空), 4int value = b[5]; // 返回下標為5的元素的引用(下標從0開始,如果下標不正確,則屬于未定義行為), 25std::vector<int>::reference ref3 = b.at(5); // 返回下標為pos的元素的引用;如果下標不正確,則拋出異常, 25x.push_back(-100); // 將元素添加到容器末尾,向容器末尾添加一個元素value = x[x.size() - 1]; // -100std::cout << "x size after push_back: " << x.size() << std::endl; // 6x.pop_back(); // 刪除最后一個元素, 彈出容器中最后一個元素(容器必須非空)value = x[x.size() - 1]; // 4std::cout << "x size after pop_back: " << x.size() << std::endl; // 5x.assign(10, -1); // 賦值,用指定元素序列替換容器內所有元素std::cout << "x size after assign: " << x.size() << std::endl; // 10std::cout << "x[0]: " << x[0] << std::endl; // -1std::cout << "a is empty: "<< a.empty() << std::endl; // 判斷向量是否為空, 0std::cout << "a size: " << a.size() << std::endl; // 獲取向量中的元素個數, 10a.clear(); // 刪除全部內容, 清空向量中的元素,相當于調用erase(begin(), end())std::cout << "size after clear: " << a.size() << std::endl; // 0std::vector<int> c;c = b; // 將b向量復制到c向量中std::cout << "a == b ?: " << (a == b) << std::endl; // == 、 != 、>、 >= 、<、 <= , 采用字典排序策略比較,a向量與b向量比較, 相等則返回1, 0std::cout << "c == b ?: " << (c == b) << std::endl; // == 、 != 、>、 >= 、<、 <= , 采用字典排序策略比較,c向量與b向量比較, 相等則返回1, 1// 插入和刪除操作將發生元素的移動(為了保持連續存儲的性質),所以之前的迭代器可能失效// 任何改變容器大小的操作都可能造成以前的迭代器失效std::cout << "b size: " << b.size() << std::endl; // 15b.insert(b.begin(), -1); // 將-1插入到向量b的起始位置前std::cout << "b[0]: " << b[0] << std::endl; // -1std::cout << "b size: " << b.size() << std::endl; // 16b.insert(b.begin() + 5, 3, -1); //將-1分別插入到向量元素位置的5-8處(共3個元素)for (int i = 0; i < b.size(); i++) {std::cout << b[i] << "  "; // -1 20 21 22 23 -1 -1 -1 24 25 ...}std::cout<<std::endl;std::vector<int> d(5, 1);std::vector<int> e(10);e.insert(e.begin(), d.begin(), d.end()); //將d.begin(), d.end()之間的全部元素插入到e.begin()前for (int i = 0; i < e.size(); i++) {std::cout << e[i] << "  "; // 1 1 1 1 1 0 0 0 ...}std::cout << std::endl;std::cout << "b size: " << b.size() << std::endl; // 19b.erase(b.begin()); // 將起始位置的元素刪除std::cout << "b size: " << b.size() << std::endl; // 18b.erase(b.begin(), b.begin() + 3); // 將(b.begin(), b.begin()+3)之間的元素刪除std::cout << "b size: " << b.size() << std::endl; // 15b.swap(c); // 交換vector的內容, a向量與c向量進行交換for (int i = 0; i < b.size(); i++) {std::cout << b[i] << "  ";}std::cout << std::endl;for (int i = 0; i < c.size(); i++) {std::cout << c[i] << "  ";}std::cout << std::endl;return 0;
}int test_vector_two_dimension()
{// reference: http://www.cnblogs.com/mr-wid/archive/2013/01/22/2871105.htmlstd::vector< std::vector<int> > b(10, std::vector<int>(5, -1));// 對部分數據進行輸入std::cin >> b[1][1];std::cin >> b[2][2];std::cin >> b[3][3];// 全部輸出for (int m = 0; m < b.size(); m++) { //b.size()獲取行向量的大小for (int n = 0; n < b[m].size(); n++) { //獲取向量中具體每個向量的大小std::cout << b[m][n] << "  ";}std::cout << std::endl;}return 0;
}
主要參考文獻:

1.?https://software.intel.com/zh-cn/blogs/2011/08/10/c-vector

2.?http://zh.cppreference.com/w/cpp/container/vector?

3.?http://www.cplusplus.com/reference/vector/vector/


GitHub:https://github.com/fengbingchun/Messy_Test

總結

以上是生活随笔為你收集整理的C++中vector的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

歡迎分享!

轉載請說明來源于"生活随笔",并保留原作者的名字。

本文地址:C++中vector的使用