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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++——容器小整理

發布時間:2025/3/15 c/c++ 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++——容器小整理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考內容來源1:https://www.cnblogs.com/mengfanrong/p/3770971.html?tdsourcetag=s_pcqq_aiomsg
參考內容來源2:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html

標準庫vector類型使用須要的頭文件:#include 。vector 是一個類模板。不是一種數據類型,vector是一種數據類型。vector的存儲空間是連續的,list不是。

一、 定義和初始化
1.vector< typeName > v1; //默認v1為空,故以下的賦值是錯誤的:v1[0]=5;
2.vectorv2(v1); 或vectorv2=v1;或vector v2(v1.begin(), v1.end()); //v2是v1的一個副本,若v1.size()>v2.size()則賦值后v2.size()被擴充為v1.size()。
3.vector< typeName > v3(n,i); //v3包括n個值為i的typeName類型元素
4.vector< typeName > v4(n); //v4含有n個值為0的元素
5.int a[4]={0,1,2,3,3}; vector v5(a,a+5); //v5的size為5,v5被初始化為a的5個值。后一個指針要指向將被拷貝的末元素的下一位置。

二、 值初始化
1> 假設沒有指定元素初始化式,標準庫自行提供一個初始化值進行值初始化。
2> 假設保存的式含有構造函數的類類型的元素,標準庫使用該類型的構造函數初始化。
3> 假設保存的式沒有構造函數的類類型的元素,標準庫產生一個帶初始值的對象,使用這個對象進行值初始化。

三、vector對象最重要的幾種操作

  • v.push_back(t) 在容器的最后加入一個值為t的數據,容器的size變大。
    另外list有push_front()函數,在前端插入,后面的元素下標依次增大。
  • v.size() 返回容器中數據的個數,size返回對應vector類定義的size_type的值。
  • v.empty() 推斷vector是否為空
  • v[n] 返回v中位置為n的元素
  • v.insert(pointer,number, content) 向v中pointer指向的位置插入number個content的內容。
    還有v. insert(pointer, content),v.insert(pointer,a[2],a[4])將a[2]到a[4]三個元素插入。
  • v.pop_back() 刪除容器的末元素,并不返回該元素。
  • v.erase(pointer1,pointer2) 刪除pointer1到pointer2中間(包含pointer1所指)的元素。
    vector中刪除一個元素后,此位置以后的元素都須要往前移動一個位置,盡管當前迭代器位置沒有自己主動加1,可是因為元素的順次前移,也就相當于迭代器的自己主動指向下一個位置一樣。
  • v1==v2 推斷v1與v2是否相等。
  • !=、<、<=、>、>= 保持這些操作符慣有含義。
  • vector::iterator p=v1.begin( ); p初始值指向v1的第一個元素。*p取所指向元素的值。對于const vector僅僅能用vector::const_iterator類型的指針訪問。
  • p=v1.end( ); p指向v1的最后一個元素的下一位置。
  • 12.v.clear() 刪除容器中的全部元素。
  • #include中的泛函算法
    搜索算法:find() 、search() 、count() 、find_if() 、search_if() 、count_if()
    分類排序:sort() 、merge()
    刪除算法:unique() 、remove()
    生成和變異:generate() 、fill() 、transformation() 、copy()
    關系算法:equal() 、min() 、max()

    四、內存管理與效率

    1.使用reserve()函數提前設定容量大小,避免多次容量擴充操作導致效率低下。

    關于STL容器,最令人稱贊的特性之中的一個就是是僅僅不超過它們的最大大小,它們就能夠自己主動增長到足以容納你放進去的數據。(要知道這個最大值,僅僅要調用名叫max_size的成員函數。)對于vector和string,假設須要很多其它空間,就以相似realloc的思想來增長大小。vector容器支持隨機訪問,因此為了提高效率,它內部使用動態數組的方式實現的。在通過 reserve() 來申請特定大小的時候總是按指數邊界來增大其內部緩沖區。當進行insert或push_back等添加元素的操作時,假設此時動態數組的內存不夠用,就要動態的又一次分配當前大小的1.5~2倍的新內存區,再把原數組的內容復制過去。所以,在普通情況下,其訪問速度同一般數組,僅僅有在又一次分配發生時,其性能才會下降。正如上面的代碼告訴你的那樣。而進行pop_back操作時,capacity并不會由于vector容器里的元素降低而有所下降,還會維持操作之前的大小。對于vector容器來說,假設有大量的數據須要進行push_back,應當使用reserve()函數提前設定其容量大小,否則會出現很多次容量擴充操作,導致效率低下。

    reserve成員函數同意你最小化必須進行的又一次分配的次數,因而能夠避免真分配的開銷和迭代器/指針/引用失效。但在我解釋reserve為什么能夠那么做之前,讓我簡要介紹有時候令人困惑的四個相關成員函數。在標準容器中,僅僅有vector和string提供了全部這些函數。

    (1) size()告訴你容器中有多少元素。它沒有告訴你容器為它容納的元素分配了多少內存。
    (2) capacity()告訴你容器在它已經分配的內存中能夠容納多少元素。那是容器在那塊內存中總共能夠容納多少元素,而不是還能夠容納多少元素。假設你想知道一個vector或string中有多少沒有被占用的內存,你必須從capacity()中減去size()。假設size和capacity返回相同的值,容器中就沒有剩余空間了,而下一次插入(通過insert或push_back等)會引發上面的又一次分配步驟。
    (3) resize(Container::size_type n)強制把容器改為容納n個元素。調用resize之后,size將會返回n。假設n小于當前大小,容器尾部的元素會被銷毀。假設n大于當前大小,新默認構造的元素會加入到容器尾部。假設n大于當前容量,在元素加入之前會發生又一次分配。
    (4) reserve(Container::size_type n)強制容器把它的容量改為至少n,提供的n不小于當前大小。這一般強迫進行一次又一次分配,由于容量須要添加。(假設n小于當前容量,vector忽略它,這個調用什么都不做,string可能把它的容量降低為size()和n中大的數,但string的大小沒有改變。在我的經驗中,使用reserve來從一個string中修整多余容量一般不如使用“交換技巧”,那是條款17的主題。)

    這個簡單介紹表示了僅僅要有元素須要插入并且容器的容量不足時就會發生又一次分配(包含它們維護的原始內存分配和回收,對象的拷貝和析構和迭代器、指針和引用的失效)。所以,避免又一次分配的關鍵是使用reserve盡快把容器的容量設置為足夠大,最好在容器被構造之后立馬進行。

    比如,假定你想建立一個容納1-1000值的vector。沒有使用reserve,你能夠像這樣來做:

    vector v;
    for (int i = 1; i <= 1000; ++i) v.push_back(i);
    在大多數STL實現中,這段代碼在循環過程中將會導致2到10次又一次分配。(10這個數沒什么奇怪的。記住vector在又一次分配發生時一般把容量翻倍,而1000約等于210。)

    把代碼改為使用reserve,我們得到這個:

    vector v;
    v.reserve(1000);
    for (int i = 1; i <= 1000; ++i) v.push_back(i);
    這在循環中不會發生又一次分配。

    在大小和容量之間的關系讓我們能夠預言什么時候插入將引起vector或string運行又一次分配,并且,能夠預言什么時候插入會使指向容器中的迭代器、指針和引用失效。比如,給出這段代碼,

    string s;

    if (s.size() < s.capacity()) {
    s.push_back(‘x’);
    }
    push_back的調用不會使指向這個string中的迭代器、指針或引用失效,由于string的容量保證大于它的大小。假設不是運行push_back,代碼在string的任何位置進行一個insert,我們仍然能夠保證在插入期間沒有發生又一次分配,可是,與伴隨string插入時迭代器失效的一般規則一致,全部從插入位置到string結尾的迭代器/指針/引用將失效。

    回到本條款的主旨,通常有兩情況使用reserve來避免不必要的又一次分配。第一個可用的情況是當你確切或者大約知道有多少元素將最后出如今容器中。那樣的話,就像上面的vector代碼,你僅僅是提前reserve適當數量的空間。另外一種情況是保留你可能須要的最大的空間,然后,一旦你加入完所有數據,修整掉不論什么多余的容量。

    2.使用“交換技巧”來修整vector過剩空間/內存

    有一種方法來把它從以前最大的容量降低到它如今須要的容量。這樣降低容量的方法經常被稱為“收縮到合適(shrink to fit)”。該方法僅僅需一條語句:vector(ivec).swap(ivec);
    表達式vector(ivec)建立一個暫時vector,它是ivec的一份拷貝:vector的拷貝構造函數做了這個工作。可是,vector的拷貝構造函數僅僅分配拷貝的元素須要的內存,所以這個暫時vector沒有多余的容量。然后我們讓暫時vector和ivec交換數據,這時我們完畢了,ivec僅僅有暫時變量的修整過的容量,而這個暫時變量則持有了以前在ivec中的沒用到的過剩容量。在這里(這個語句結尾),暫時vector被銷毀,因此釋放了以前ivec使用的內存,收縮到合適。

    3.用swap方法強行釋放STL Vector所占內存

    template < class T> void ClearVector( vector& v )
    {
    vectorvtTemp;
    vtTemp.swap( v );
    }

    vector v ;
    nums.push_back(1);
    nums.push_back(3);
    nums.push_back(2);
    nums.push_back(4);
    vector().swap(v);

    /* 或者v.swap(vector()); */

    /或者{ std::vector tmp = v; v.swap(tmp); }; //加大括號{ }是讓tmp退出{ }時自己主動析構/

    五、Vector 內存管理成員函數的行為測試
    C++ STL的vector使用很廣泛,可是對其內存的管理模型一直有多種推測,以下用實例代碼測試來了解其內存管理方式,測試代碼例如以下:

    #include
    #include
    using namespace std;

    int main()
    {
    vector iVec;
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //1個元素, 容器容量為1

    iVec.push_back(1);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //2個元素, 容器容量為2

    iVec.push_back(2);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //3個元素, 容器容量為4

    iVec.push_back(3);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //4個元素, 容器容量為4

    iVec.push_back(4);
    iVec.push_back(5);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //5個元素, 容器容量為8

    iVec.push_back(6);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //6個元素, 容器容量為8

    iVec.push_back(7);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //7個元素, 容器容量為8

    iVec.push_back(8);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //8個元素, 容器容量為8

    iVec.push_back(9);
    cout << "容器 大小為: " << iVec.size() << endl;
    cout << "容器 容量為: " << iVec.capacity() << endl; //9個元素, 容器容量為16
    /* vs2005/8 容量增長不是翻倍的,如
    9個元素 容量9
    10個元素 容量13 */

    /* 測試effective stl中的特殊的交換 swap() */
    cout << "當前vector 的大小為: " << iVec.size() << endl;
    cout << "當前vector 的容量為: " << iVec.capacity() << endl;
    vector(iVec).swap(iVec);

    cout << "暫時的vector對象 的大小為: " << (vector(iVec)).size() << endl;
    cout << "暫時的vector對象 的容量為: " << (vector(iVec)).capacity() << endl;
    cout << "交換后,當前vector 的大小為: " << iVec.size() << endl;
    cout << "交換后,當前vector 的容量為: " << iVec.capacity() << endl;

    return 0;
    }

    六、實例
    1.pop_back()&push_back(elem)實例在容器最后移除和插入數據
    實例

    #include <string.h>#include <vector> #include <iostream> using namespace std; int main() {vector<int>obj;//創建一個向量存儲容器 intfor(int i=0;i<10;i++) // push_back(elem)在數組最后添加數據 {obj.push_back(i);cout<<obj[i]<<","; }for(int i=0;i<5;i++)//去掉數組最后一個數據 {obj.pop_back();}cout<<"\n"<<endl;for(int i=0;i<obj.size();i++)//size()容器中實際數據個數 {cout<<obj[i]<<",";}return 0; }

    輸出結果為:
    0,1,2,3,4,5,6,7,8,9,
    0,1,2,3,4

    2.clear()清除容器中所有數據
    實例

    #include <string.h> #include <vector> #include <iostream> using namespace std;int main() {vector<int>obj;for(int i=0;i<10;i++)//push_back(elem)在數組最后添加數據 {obj.push_back(i);cout<<obj[i]<<",";}obj.clear();//清除容器中所以數據for(int i=0;i<obj.size();i++){cout<<obj[i]<<endl;}return 0; }

    輸出結果為:
    0,1,2,3,4,5,6,7,8,9,

    3.排序
    實例

    #include <string.h> #include <vector> #include <iostream> #include <algorithm> using namespace std;int main() {vector<int>obj;obj.push_back(1);obj.push_back(3);obj.push_back(0);sort(obj.begin(),obj.end());//從小到大cout<<"從小到大:"<<endl;for(int i=0;i<obj.size();i++){cout<<obj[i]<<","; } cout<<"\n"<<endl;cout<<"從大到小:"<<endl;reverse(obj.begin(),obj.end());//從大到小 for(int i=0;i<obj.size();i++){cout<<obj[i]<<",";}return 0; }

    輸出結果為:
    從小到大:
    0,1,3,
    從大到小:
    3,1,0,

    1.注意 sort 需要頭文件 #include

    2.如果想 sort 來降序,可重寫 sort

    bool compare(int a,int b) { return a< b; //升序排列,如果改為return a>b,則為降序 } int a[20]={2,4,1,23,5,76,0,43,24,65},i; for(i=0;i<20;i++) cout<< a[i]<< endl; sort(a,a+20,compare);

    4.訪問(直接數組訪問&迭代器訪問)
    實例

    #include <string.h> #include <vector> #include <iostream> #include <algorithm> using namespace std;int main() {//順序訪問vector<int>obj;for(int i=0;i<10;i++){obj.push_back(i); } cout<<"直接利用數組:"; //方法一for(int i=0;i<10;i++) {cout<<obj[i]<<" ";}cout<<endl; cout<<"利用迭代器:" ;//方法二,使用迭代器將容器中數據輸出 vector<int>::iterator it;//聲明一個迭代器,來訪問vector容器,作用:遍歷或者指向vector容器的元素 for(it=obj.begin();it!=obj.end();it++){cout<<*it<<" ";}return 0; }

    輸出結果為:
    直接利用數組:0 1 2 3 4 5 6 7 8 9
    利用迭代器:0 1 2 3 4 5 6 7 8 9

    5.二維數組兩種定義方法(結果一樣)

    方法一 #include <string.h> #include <vector> #include <iostream> #include <algorithm> using namespace std;int main() {int N=5, M=6; vector<vector<int> > obj(N); //定義二維動態數組大小5行 for(int i =0; i< obj.size(); i++)//動態二維數組為5行6列,值全為0 { obj[i].resize(M); } for(int i=0; i< obj.size(); i++)//輸出二維動態數組 {for(int j=0;j<obj[i].size();j++){cout<<obj[i][j]<<" ";}cout<<"\n";}return 0; }方法二 #include <string.h> #include <vector> #include <iostream> #include <algorithm> using namespace std;int main() {int N=5, M=6; vector<vector<int> > obj(N, vector<int>(M)); //定義二維動態數組5行6列 for(int i=0; i< obj.size(); i++)//輸出二維動態數組 {for(int j=0;j<obj[i].size();j++){cout<<obj[i][j]<<" ";}cout<<"\n";}return 0; }

    輸出結果為:
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0

    總結

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

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