亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++ vector的用法小結

2020-01-26 15:40:26
字體:
來源:轉載
供稿:網友

c++ vector用法

C++內置的數組支持容器的機制,但是它不支持容器抽象的語義。要解決此問題我們自己實現這樣的類。在標準C++中,用容器向量(vector)實現。容器向量也是一個類模板。

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

一、 定義和初始化

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

二、 值初始化

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

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

1. v.push_back(t)    在容器的最后添加一個值為t的數據,容器的size變大。
                     另外list有push_front()函數,在前端插入,后面的元素下標依次增大。
2. v.size()        返回容器中數據的個數,size返回相應vector類定義的size_type的值。v.resize(2*v.size)或                  
v.resize(2*v.size, 99) 將v的容量翻倍(并把新元素的值初始化為99)
3. v.empty()     判斷vector是否為空
4. v[n]           返回v中位置為n的元素
5. v.insert(pointer,number, content)    向v中pointer指向的位置插入number個content的內容。
                  還有v. insert(pointer, content),v.insert(pointer,a[2],a[4])將a[2]到a[4]三個元素插入。
6. v.pop_back()    刪除容器的末元素,并不返回該元素。
7.v.erase(pointer1,pointer2) 刪除pointer1到pointer2中間(包括pointer1所指)的元素。
                   vector中刪除一個元素后,此位置以后的元素都需要往前移動一個位置,雖然當前迭代器位置沒有自動加1,
                   但是由于后續元素的順次前移,也就相當于迭代器的自動指向下一個位置一樣。
8. v1==v2          判斷v1與v2是否相等。
9. !=、<、<=、>、>=      保持這些操作符慣有含義。
10. vector<typeName>::iterator p=v1.begin( ); p初始值指向v1的第一個元素。*p取所指向元素的值。
                    對于const vector<typeName>只能用vector<typeName>::const_iterator類型的指針訪問。
11.   p=v1.end( ); p指向v1的最后一個元素的下一位置。
12.v.clear()      刪除容器中的所有元素。12.v.clear()      刪除容器中的所有元素。
#include<algorithm>中的泛函算法
搜索算法:find() 、search() 、count() 、find_if() 、search_if() 、count_if()
分類排序:sort() 、merge()
刪除算法:unique() 、remove()
生成和變異:generate() 、fill() 、transformation() 、copy()
關系算法:equal() 、min() 、max()
sort(v1.begin(),vi.begin()+v1.size/2); 對v1的前半段元素排序
list<char>::iterator pMiddle =find(cList.begin(),cList.end(),'A');找到則返回被查內容第一次出現處指針,否則返回end()。
vector< typeName >::size_type x ; vector< typeName >類型的計數,可用于循環如同for(int i)
初學C++的程序員可能會認為vector的下標操作可以添加元素,其實不然:
vector<int> ivec;   // empty vector
for (vector<int>::size_type ix = 0; ix != 10; ++ix)
     ivec[ix] = ix; // disaster: ivec has no elements
上述程序試圖在ivec中插入10個新元素,元素值依次為0到9的整數。但是,這里ivec是空的vector對象,而且下標只能用于獲取已存在的元素。
這個循環的正確寫法應該是:
for (vector<int>::size_type ix = 0; ix != 10; ++ix)
     ivec.push_back(ix); // ok: adds new element with value ix
警告:必須是已存在的元素才能用下標操作符進行索引。通過下標操作進行賦值時,不會添加任何元素。僅能對確知已存在的元素進行下標操作  
  
四、內存管理與效率

      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<int>。沒有使用reserve,你可以像這樣來做:

vector<int> v;
for (int i = 1; i <= 1000; ++i) v.push_back(i);

在大多數STL實現中,這段代碼在循環過程中將會導致2到10次重新分配。(10這個數沒什么奇怪的。記住vector在重新分配發生時一般把容量翻倍,而1000約等于210。)
把代碼改為使用reserve,我們得到這個:

vector<int> 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過??臻g/內存
      有一種方法來把它從曾經最大的容量減少到它現在需要的容量。這樣減少容量的方法常常被稱為“收縮到合適(shrink to fit)”。該方法只需一條語句:vector<int>(ivec).swap(ivec);
表達式vector<int>(ivec)建立一個臨時vector,它是ivec的一份拷貝:vector的拷貝構造函數做了這個工作。但是,vector的拷貝構造函數只分配拷貝的元素需要的內存,所以這個臨時vector沒有多余的容量。然后我們讓臨時vector和ivec交換數據,這時我們完成了,ivec只有臨時變量的修整過的容量,而這個臨時變量則持有了曾經在ivec中的沒用到的過剩容量。在這里(這個語句結尾),臨時vector被銷毀,因此釋放了以前ivec使用的內存,收縮到合適。
     3.用swap方法強行釋放STL Vector所占內存

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

    vector<int> v ;
    nums.push_back(1);
    nums.push_back(3);
    nums.push_back(2);
    nums.push_back(4);
    vector<int>().swap(v);
/* 或者v.swap(vector<int>()); */
/*或者{ std::vector<int> tmp = v;   v.swap(tmp);   }; //加大括號{ }是讓tmp退出{ }時自動析構*/

五、Vector 內存管理成員函數的行為測試

C++ STL的vector使用非常廣泛,但是對其內存的管理模型一直有多種猜測,下面用實例代碼測試來了解其內存管理方式,測試代碼如下:

#include <iostream>#include <vector>using namespace std;int main(){vector<int> iVec;cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //1個元素, 容器容量為1iVec.push_back(1);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //2個元素, 容器容量為2iVec.push_back(2);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //3個元素, 容器容量為4iVec.push_back(3);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //4個元素, 容器容量為4iVec.push_back(4);iVec.push_back(5);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //5個元素, 容器容量為8iVec.push_back(6);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //6個元素, 容器容量為8iVec.push_back(7);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //7個元素, 容器容量為8iVec.push_back(8);cout << "容器 大小為: " << iVec.size() << endl;cout << "容器 容量為: " << iVec.capacity() << endl; //8個元素, 容器容量為8iVec.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<int>(iVec).swap(iVec);cout << "臨時的vector<int>對象 的大小為: " << (vector<int>(iVec)).size() << endl;cout << "臨時的vector<int>對象 的容量為: " << (vector<int>(iVec)).capacity() << endl;cout << "交換后,當前vector 的大小為: " << iVec.size() << endl;cout << "交換后,當前vector 的容量為: " << iVec.capacity() << endl;return 0;}

六、vector的其他成員函數

c.assign(beg,end)
將[beg; end)區間中的數據賦值給c。
c.assign(n,elem)
將n個elem的拷貝賦值給c。
c.at(idx)
傳回索引idx所指的數據,如果idx越界,拋出out_of_range。
c.back()
傳回最后一個數據,不檢查這個數據是否存在。
c.front()
傳回地一個數據。
get_allocator
使用構造函數返回一個拷貝。
c.rbegin()
傳回一個逆向隊列的第一個數據。
c.rend()
傳回一個逆向隊列的最后一個數據的下一個位置。
c.~ vector <Elem>()
銷毀所有數據,釋放內存。  

以下是其它網友的補充:

1 、基本操作

(1)頭文件#include<vector>.

(2)創建vector對象,vector<int> vec;

(3)尾部插入數字:vec.push_back(a);

(4)使用下標訪問元素,cout<<vec[0]<<endl;記住下標是從0開始的。

(5)使用迭代器訪問元素.

vector<int>::iterator it;for(it=vec.begin();it!=vec.end();it++)  cout<<*it<<endl;

(6)插入元素:    vec.insert(vec.begin()+i,a);在第i+1個元素前面插入a;

(7)刪除元素:    vec.erase(vec.begin()+2);刪除第3個元素

vec.erase(vec.begin()+i,vec.end()+j);刪除區間[i,j-1];區間從0開始

(8)向量大小:vec.size();

(9)清空:vec.clear();

2、vector的元素不僅僅可以使int,double,string,還可以是結構體,但是要注意:結構體要定義為全局的,否則會出錯。下面是一段簡短的程序代碼:

#include<stdio.h>#include<algorithm>#include<vector>#include<iostream>using namespace std;typedef struct rect{ int id; int length; int width;  //對于向量元素是結構體的,可在結構體內部定義比較函數,下面按照id,length,width升序排序?! ool operator< (const rect &a) const {  if(id!=a.id)   return id<a.id;  else  {   if(length!=a.length)    return length<a.length;   else    return width<a.width;  } }}Rect;int main(){ vector<Rect> vec; Rect rect; rect.id=1; rect.length=2; rect.width=3; vec.push_back(rect); vector<Rect>::iterator it=vec.begin(); cout<<(*it).id<<' '<<(*it).length<<' '<<(*it).width<<endl; return 0;}

3  算法

(1) 使用reverse將元素翻轉:需要頭文件#include<algorithm>

reverse(vec.begin(),vec.end());將元素翻轉(在vector中,如果一個函數中需要兩個迭代器,

一般后一個都不包含.)

(2)使用sort排序:需要頭文件#include<algorithm>,

sort(vec.begin(),vec.end());(默認是按升序排列,即從小到大).

可以通過重寫排序比較函數按照降序比較,如下:

定義排序比較函數:

復制代碼 代碼如下:

bool Comp(const int &a,const int &b)
{
    return a>b;
}

調用時:sort(vec.begin(),vec.end(),Comp),這樣就降序排序。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品中国老女人| 最新国产成人av网站网址麻豆| 在线观看视频99| 日韩精品视频中文在线观看| 久久影院资源站| 91色琪琪电影亚洲精品久久| 在线电影av不卡网址| 久久久免费av| www.日韩.com| 成人国产精品日本在线| 精品视频在线观看日韩| 91久久精品美女| 国产精品一区久久| 国产91精品久久久| 5566日本婷婷色中文字幕97| 亚洲一区二区久久久久久久| 中文字幕亚洲一区在线观看| 成人性生交xxxxx网站| 久久精品色欧美aⅴ一区二区| 亚洲free性xxxx护士白浆| 亚洲人成网站色ww在线| 日本久久久久久久久久久| 欧美野外wwwxxx| 色噜噜久久综合伊人一本| 欧美福利在线观看| 欧美天堂在线观看| 成人av番号网| 国产精品久久久久福利| 日韩精品免费在线视频| 欧美理论在线观看| 国产成人福利网站| 国产成人av网址| 色系列之999| 日韩中文视频免费在线观看| 热久久这里只有精品| 欧美丰满少妇xxxxx| 国产亚洲一级高清| 亚洲午夜国产成人av电影男同| 亚洲精品日韩欧美| 精品国产31久久久久久| 久操成人在线视频| 欧美性猛交xxxx乱大交| 亚洲精品999| 成人xxxx视频| 日韩精品久久久久久久玫瑰园| 国产亚洲精品va在线观看| 国产精品国产福利国产秒拍| 成人黄色午夜影院| 亚洲曰本av电影| 日韩乱码在线视频| 狠狠色香婷婷久久亚洲精品| 懂色av影视一区二区三区| 亚洲欧美综合另类中字| 亚洲tv在线观看| 一级做a爰片久久毛片美女图片| 在线不卡国产精品| 亚洲欧美中文另类| 92福利视频午夜1000合集在线观看| 欧美国产第一页| www.99久久热国产日韩欧美.com| 成人精品在线观看| 亚洲xxx视频| 国产不卡av在线免费观看| 亚洲最大成人免费视频| 日韩欧美亚洲范冰冰与中字| 欧美丰满少妇xxxxx做受| 久久频这里精品99香蕉| 国产98色在线| 国产亚洲精品综合一区91| 久久夜精品va视频免费观看| 日韩av色综合| 91九色国产在线| 国产精品视频大全| 欧美精品九九久久| 久久精品视频在线播放| 国产精品爱啪在线线免费观看| 亚洲自拍高清视频网站| 亚洲韩国日本中文字幕| 国产精品一香蕉国产线看观看| 亚洲天堂av图片| 亚洲精品福利在线| 成人免费黄色网| 日韩精品极品毛片系列视频| 国产精品久久久久久久久| 亚洲人成免费电影| 精品久久久久久久久久久| 国产精品欧美亚洲777777| 欧美成人在线网站| 日韩一区视频在线| 亚洲成人精品av| 欧美自拍大量在线观看| 日韩av一区在线| 欧美综合在线第二页| 456亚洲影院| 国产一区二区丝袜高跟鞋图片| 亚洲福利在线播放| 久久精品国产成人| 亚洲成人性视频| 欧美激情免费观看| 欧美精品在线观看91| 91在线视频精品| 欧美中文字幕在线播放| 国产xxx69麻豆国语对白| 国产精品吊钟奶在线| 精品成人av一区| 成人精品一区二区三区| 精品无码久久久久久国产| 日韩精品视频中文在线观看| 亚洲a∨日韩av高清在线观看| 欧美日韩免费观看中文| 日韩欧中文字幕| 久久久国产精品亚洲一区| 日本一欧美一欧美一亚洲视频| 欧美综合国产精品久久丁香| 日韩黄在线观看| 久久精彩免费视频| 日韩欧美成人免费视频| 亚洲视频在线观看视频| 97超级碰碰碰久久久| 中文字幕视频在线免费欧美日韩综合在线看| 中文字幕精品—区二区| 亚洲第一中文字幕| 日韩美女主播视频| 91亚洲国产精品| www.色综合| 欧美多人乱p欧美4p久久| 色噜噜亚洲精品中文字幕| 69久久夜色精品国产7777| 欧美高清在线观看| 欧美日韩国产一区二区三区| 国产精品高潮呻吟视频| 粉嫩av一区二区三区免费野| 日韩av在线网页| 日韩精品免费综合视频在线播放| 另类专区欧美制服同性| 亚洲少妇中文在线| 欧美在线视频观看| 奇门遁甲1982国语版免费观看高清| 国产不卡视频在线| 2019中文字幕在线免费观看| 日韩电影在线观看永久视频免费网站| 91精品国产综合久久香蕉的用户体验| 欧美精品成人91久久久久久久| 98精品国产高清在线xxxx天堂| 精品欧美一区二区三区| 欧美极品第一页| 国产成人在线一区| 亚洲自拍偷拍区| 日韩中文字幕在线视频播放| 久久九九亚洲综合| 久久久亚洲成人| 国产精品一区二区女厕厕| 日本欧美一二三区| 亚洲欧美日韩中文在线| 日韩欧美aaa| 国产美女高潮久久白浆| 亚洲国产成人在线视频| 国产精品久久久久久久美男| 国产91在线播放精品91| 中文字幕国产日韩| 国产自摸综合网| 国产精品一区二区三区久久| 中文字幕视频在线免费欧美日韩综合在线看| 成人午夜小视频|