目錄
創(chuàng)新互聯(lián)建站是專(zhuān)業(yè)的京山網(wǎng)站建設(shè)公司,京山接單;提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行京山網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!引言
空間配置器
vector
vector容器與string容器的一些差異
接口介紹——reserve
resize接口
shrink_to_fit 接口
operator[ ] 和 at 接口
assign接口
增刪查改接口
swap接口
例題講解
vector實(shí)質(zhì)上就是數(shù)據(jù)結(jié)構(gòu)的順序表,也可以簡(jiǎn)單地理解為數(shù)組,它在庫(kù)中的實(shí)現(xiàn)與之前我們所學(xué)的string有很多相似之處,重復(fù)的地方在此不多贅述。
空間配置器可以看到庫(kù)里vector的模板參數(shù)第一項(xiàng)是實(shí)例化的類(lèi)型,也就是順序表實(shí)例化時(shí)里面的元素是int還是double的......vector
第二個(gè)參數(shù)是空間配置器,這個(gè)概念相對(duì)復(fù)雜一點(diǎn),是一種底層實(shí)現(xiàn)機(jī)制,在使用層面我們可以暫時(shí)不用管。說(shuō)明一下以防產(chǎn)生誤解。
vector首先說(shuō)明vector
第二個(gè)差異在于大小的比較,vector
第三個(gè)差異在于接口上,它們之間的接口也有很大區(qū)別,功能的不同,實(shí)現(xiàn)上的不同等等。比如對(duì)于操作符+=的重載,string有+=,可以直接在字符串后面加字符\字符串,而vector
其它的不同更多體現(xiàn)在vector 與 string整體的不同上,后面講接口的時(shí)候會(huì)順帶提出。
vector容器與string容器的一些差異上面是vector
string是早期設(shè)計(jì)的,與后面容器的實(shí)現(xiàn)有時(shí)代的隔閡,string的接口龐雜繁復(fù),數(shù)量是vector的一倍,其實(shí)有很多接口是沒(méi)有什么意義的或者基本不會(huì)使用的,但由于向前兼容的特性這些接口都保留了下來(lái)。
在insert、erase這些增刪接口上面,string與其他容器(如:vector) 的標(biāo)識(shí)也不同,string是使用下標(biāo)標(biāo)識(shí)位置的,而vector等容器是用迭代器標(biāo)識(shí)位置的 (insert(v.begin()+4,1) )
接口介紹——reservereserve接口主要是擴(kuò)容,通過(guò)改變capacity的大小達(dá)成目的。
接口本身很簡(jiǎn)單易懂,但既然能改變capacity能擴(kuò)容,那能不能縮容呢?
————一般來(lái)說(shuō)是不會(huì)實(shí)現(xiàn)縮容的,因?yàn)榭s容是有代價(jià)的,不是想縮就縮的。
縮容實(shí)質(zhì)上是開(kāi)一塊新空間拷貝數(shù)據(jù),是以空間換時(shí)間的方式。
縮容需要先開(kāi)新空間,拷貝數(shù)據(jù)過(guò)去,然后釋放舊空間,頻繁縮容就會(huì)反復(fù)開(kāi)空間、釋放和拷貝,會(huì)有較大代價(jià)所以一般不會(huì)縮容。
有人會(huì)問(wèn):為什么不能直接縮容釋放不需要的一塊空間給操作系統(tǒng),要開(kāi)新空間拷貝數(shù)據(jù)呢?
————這樣當(dāng)然是不行的,和內(nèi)存管理機(jī)制有關(guān)。
類(lèi)似malloc一塊空間是不能分兩次free還給操作系統(tǒng)的。
resize接口是個(gè)非常重要的接口,主要是改變size,它不改變capacity,有四種情況:
1、沒(méi)有開(kāi)空間時(shí),resize開(kāi)空間+初始化(
2、容量不夠時(shí),擴(kuò)容。如capacity為9,resize(20),此時(shí)空間不夠會(huì)先擴(kuò)容。
3、容量夠時(shí),會(huì)從初始size位置填數(shù)據(jù)直到當(dāng)前size位置。
4、resize的size值比初始值小時(shí)會(huì)刪除數(shù)據(jù),注意不會(huì)刪除空間!只是刪除有效數(shù)據(jù)!
那么庫(kù)里面給的接口,參數(shù)方面我們似乎看不懂,size_type 和 value_type是什么類(lèi)型,這是由于庫(kù)在里面再次typedef了這些類(lèi)型,在Member types可以查到:
我們可以看到size_type 其實(shí)就是size_t類(lèi)型
value_type則是第一個(gè)模板參數(shù),也就是我們這里的T,class
所以庫(kù)里面的函數(shù)定義翻譯過(guò)來(lái)就是void resize(size_t n , T =T() )
n 是改變的size的大小,T = T() 是調(diào)用了系統(tǒng)默認(rèn)構(gòu)造函數(shù)。
由此可以應(yīng)證C++內(nèi)置類(lèi)型也需要(也有)默認(rèn)構(gòu)造函數(shù)的概念,因?yàn)橄襁@種類(lèi)似的場(chǎng)景用得到。
如果T是內(nèi)置類(lèi)型不是自定義類(lèi)型,如何調(diào)用默認(rèn)構(gòu)造,所以內(nèi)置類(lèi)型也有默認(rèn)構(gòu)造函數(shù)的概念。
shrink_to_fit 接口上面我們說(shuō)了一般來(lái)說(shuō)不會(huì)輕易縮容,因?yàn)榇鷥r(jià)比較大,像reserve只擴(kuò)不縮,resize、clear都不動(dòng)capacity,但是shrink_to_fit 接口是實(shí)現(xiàn)來(lái)縮容的,與上面reserve、resize相反,是 “以空間換時(shí)間 ”。
擴(kuò)容一般是實(shí)現(xiàn)兩倍擴(kuò)容,像Linux等平臺(tái)下都是兩倍,也有些平臺(tái)是1.5倍擴(kuò)容,像VS,具體看編譯器實(shí)現(xiàn),兩倍擴(kuò)容一般用的比較多一點(diǎn)。
operator[ ] 和 at 接口兩個(gè)接口都是用來(lái)遍歷訪問(wèn)vector中的數(shù)據(jù)的,存在著一定差異。
相同之處是使用方式類(lèi)似,都是通過(guò)下標(biāo)獲得數(shù)據(jù)。并且都提供了const和非const兩個(gè)版本。
為什么要提供兩個(gè)版本?————
1、只讀接口函數(shù)只有const版本的(如:size函數(shù))只能由const對(duì)象調(diào)用
2、只寫(xiě)函數(shù)接口只有非const版本的(如:push_back函數(shù)),只能由非const(普通)對(duì)象調(diào)用
3、可讀可寫(xiě)接口函數(shù),const+非const都提供(如:operator[]),兩者都能調(diào)用
注意這里的[ ]是函數(shù)調(diào)用,不是單純的操作符,與數(shù)組不同。
operator[ ]和at的區(qū)別在于越界的情況下,[ ] 內(nèi)部實(shí)現(xiàn)的時(shí)候是assert斷言下標(biāo)位置pos< size的,
而at 則是通過(guò)拋異常的方式報(bào)錯(cuò)。(注:assert在debug下有效,relase下不產(chǎn)生效果)
assign接口assign 有2種用法:
用法 1、覆蓋賦值,這種方式會(huì)覆蓋掉之前所有數(shù)據(jù)。
vectora;
a.resize(5);
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
for (auto e : a)
{
cout<< e<< "";
}
cout<< endl;
a.assign(9, 1);
for (auto e : a)
{
cout<< e<< "";
}
cout<< endl;
從結(jié)果來(lái)看確實(shí)覆蓋了之前的數(shù)據(jù)。
用法 2、支持迭代器區(qū)間
庫(kù)里面給的接口參數(shù)就是迭代器區(qū)間? [first,last) \ [begin,end) ,是左閉右開(kāi)的。
使用方式:
vectoraa;
aa.resize(5);
for (auto e : aa)
{
cout<< e<< " ";
}
cout<< endl;
size_t i = 0;
vectorbb;
bb.resize(5);
for (auto &e : bb)
{
e = i++;
}
aa.assign(bb.begin(), bb.end());
for (auto e : aa)
{
cout<< e<< " ";
}
cout<< endl;
再看參數(shù)類(lèi)型,我們發(fā)現(xiàn)庫(kù)里給參數(shù)迭代器也寫(xiě)了一個(gè)模板,有人會(huì)問(wèn):直接寫(xiě)成iterator不就行了,為什么還要寫(xiě)個(gè)迭代器模板?
————因?yàn)槿绻麊螌?xiě)迭代器就只支持vector下的迭代器區(qū)間,寫(xiě)成模板的話可以支持其他容器的迭代器區(qū)間,比如:
這樣就支持了string容器的迭代器區(qū)間。
也可以這樣使用:
與上面對(duì)比一下,發(fā)現(xiàn)區(qū)間確實(shí)像期望所改變了。
增刪查改接口數(shù)據(jù)結(jié)構(gòu)最重要的一環(huán)可以說(shuō)是增刪查改了。
增:最常用的是push_back,但是push_back適用于尾插,而在順序表中一般不建議在中間位置插入(尤其是頭插),因?yàn)檫@樣會(huì)挪動(dòng)數(shù)據(jù),效率低下。所以insert接口使用沒(méi)有push_back頻繁。
另外insert可以插入一個(gè)元素,也可以插入一段數(shù)據(jù)。
刪:最常用的是pop_back,但是pop_back適用于尾刪,和增一樣,其他情況會(huì)挪動(dòng)數(shù)據(jù),因此erase接口也使用不那么頻繁。
另外刪可以刪除單個(gè)位置數(shù)據(jù),也可以直接刪除一段數(shù)據(jù)。
查:在vector容器庫(kù)中發(fā)現(xiàn)沒(méi)有期望的find接口,這是怎么回事?————因?yàn)檫@個(gè)接口在每個(gè)容器中實(shí)現(xiàn)的方式都是一樣的,都是遍歷迭代器,找到了就返回對(duì)應(yīng)的迭代器位置,所以不會(huì)特地在每個(gè)容器中都寫(xiě)一個(gè)find,而是將它拉出來(lái)寫(xiě)個(gè)模板,使得每個(gè)容器都能直接使用。
可以看到find是從first位置開(kāi)始查找,到 last位置結(jié)束,找到了返回此時(shí)的迭代器,沒(méi)找到就返回last位置的迭代器(這也體現(xiàn)了迭代器區(qū)間左閉右開(kāi),last不在區(qū)間中)。
使用方式:
vector::iterator it = find(aa.begin(), aa.end(), 101);
if (it != aa.end())
{
aa.insert(it, 0);
}
for (auto e : aa)
{
cout<< e<< " ";
}
cout<< endl;
這里找到了就在當(dāng)前迭代器位置之前插入0,沒(méi)找到就不插入。
改:改的話主要是通過(guò)operator[ ] 來(lái)實(shí)現(xiàn)。
swap接口vector中自己實(shí)現(xiàn)了一個(gè)swap函數(shù),因?yàn)閹?kù)里的swap函數(shù)交換代價(jià)太大,需要深拷貝。
容器中實(shí)現(xiàn)的可以直接完成交換,大大降低了代價(jià)開(kāi)銷(xiāo)。
vectorbb;
bb.push_back(1);
aa.swap(bb);
for (auto e : aa)
{
cout<< e<< " ";
}
cout<< endl;
LeetCode118.楊輝三角
首先看到題目的圖要明確一點(diǎn):要實(shí)現(xiàn)的二維數(shù)組是每一行的元素個(gè)數(shù)不同,但并非按圖上畫(huà)的那般順序排列,二維數(shù)組的圖應(yīng)該是這樣的:
題中給的接口樣式需要返回的是二維數(shù)組地址,傳進(jìn)來(lái)的是二維數(shù)組的行數(shù)。
對(duì)于這種問(wèn)題,我們可以先創(chuàng)建一個(gè)二維數(shù)組模型,先建立行,再通過(guò)行來(lái)創(chuàng)建列,從而通過(guò)二維數(shù)組的下標(biāo)訪問(wèn)每個(gè)元素。
創(chuàng)建二維數(shù)組模型:vector
建立行:vv.resize(numRows);? //傳參行數(shù)為numRows
通過(guò)行建立列(通過(guò)for循環(huán)實(shí)現(xiàn)):
for (int i = 0; i< vv.size(); ++i)
{
vv[i].resize(i + 1, 0);
}
同時(shí)觀察楊輝三角圖,每行首末元素都為1,所以在循環(huán)中將首末元素賦值為1:
for (int i = 0; i< vv.size(); ++i)
{
vv[i].resize(i + 1, 0);
vv[i][0] = vv[i][vv[i].size() - 1] = 1;
}
此時(shí)二維數(shù)組建立完成,首末元素為1,其余元素為0. 再觀察圖,發(fā)現(xiàn)每行非1元素 = 上一行同列元素 + 上一行同列元素前一個(gè);
于是用for循環(huán)將每個(gè)非1元素的值填上:
for (int i = 0; i< vv.size(); ++i)
{
for (int j = 0; j< vv[i].size(); ++j)
{
if (vv[i][j] == 0)
{
vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
}
}
}
最后返回二維數(shù)組首元素地址vv就可以了。
完整代碼如下:
class Solution {
public:
vector>generate(int numRows) {
vector>vv;
vv.resize(numRows);
for (int i = 0; i< vv.size(); ++i)
{
vv[i].resize(i + 1, 0);
vv[i][0] = vv[i][vv[i].size() - 1] = 1;
}
for (int i = 0; i< vv.size(); ++i)
{
for (int j = 0; j< vv[i].size(); ++j)
{
if (vv[i][j] == 0)
{
vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
}
}
}
return vv;
}
};
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文題目:vector使用指南-創(chuàng)新互聯(lián)
分享路徑:http://aaarwkj.com/article0/cdhdoo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷(xiāo)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站改版、商城網(wǎng)站、定制網(wǎng)站、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容