手写vector
前言
近來(lái)做到一些題目,對(duì)于暴力有些卡空間,對(duì)于幾個(gè)能拿分的subtask沒(méi)個(gè)剛好都能過(guò)去,但是開(kāi)的數(shù)組不一樣,都開(kāi)就MLE了,我就嘗試著開(kāi)同一個(gè)數(shù)組,卡的太緊,最后很多數(shù)據(jù)都MLE沒(méi)分了,一氣之下覺(jué)定學(xué)習(xí)動(dòng)態(tài)開(kāi)內(nèi)存(順便學(xué)習(xí)一下手寫(xiě)vector)
vector簡(jiǎn)介
vector?著名STL之一,又稱動(dòng)態(tài)數(shù)組,簡(jiǎn)直就是一個(gè)數(shù)組,有點(diǎn)像個(gè)棧
支持壓入,彈出(push_back,pop_back)這個(gè)均攤O(1)
支持隨機(jī)尋址
然后支持erase?刪除中間一個(gè)數(shù),可惜是O(n)的,然而跑的飛快(手寫(xiě)的vector里沒(méi)寫(xiě)~逃~)
其它功能基本不用
實(shí)現(xiàn)方式
vector尋址O(1)是因?yàn)樗膬?nèi)存連續(xù),一個(gè)vector由一個(gè)數(shù)組指針(后面代碼中的Data,之后的變量也會(huì)用括號(hào)表示)、一個(gè)當(dāng)前總可用存儲(chǔ)大小(Len),已用存儲(chǔ)大小(Size)
壓入元素:如果存儲(chǔ)的地方用完了,那么就把存儲(chǔ)數(shù)組開(kāi)大一倍
彈出元素:如果使用的存儲(chǔ)占不到總存儲(chǔ)的1/4那么就把存儲(chǔ)數(shù)組減小一半
代碼
下面這份代碼里的class是首先的vector,后面是對(duì)速度的測(cè)驗(yàn)
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<cstdlib> #include<ctime> template<typename T> class Vector {private:T* Data;int Len,Size;public:inline Vector(){Data=NULL;Len=Size=0;}inline Vector(const Vector& other){if(this==&other||!Len)return;Data=(T*)malloc(sizeof(T)*other.Len);for(register int i=0;i<other.Size;i++)Data[i]=other.Data[i];Len=other.Len,Size=other.Size;}inline T &operator[](const int x){return Data[x];}const Vector&push_back(const T x){if(Size==Len){Len=Len==0?1:Len<<1;T* newData=(T*)malloc(sizeof(T)*Len);memcpy(newData,Data,Size*sizeof(T));free(Data);Data=newData;}Data[Size++]=x;return *this;}const Vector&pop_back(){Size--;if(Size==(Len>>2)){Len=Len>>1;T* newData=(T*)malloc(sizeof(T)*Len);memcpy(newData,Data,Size*sizeof(T));free(Data);Data=newData;}return *this;}inline unsigned int size(){return Size;}inline unsigned int len(){return Len;} }; int tim; Vector<int>a,b,c,d,e; std::vector<int>A,B,C,D,E; int main() {tim=clock();for(int i=1;i<=10000000;i++)a.push_back(i);for(int i=1;i<=10000000;i++)a.pop_back();for(int i=1;i<=10000000;i++)b.push_back(i);for(int i=1;i<=10000000;i++)b.pop_back();for(int i=1;i<=10000000;i++)c.push_back(i);for(int i=1;i<=10000000;i++)c.pop_back();for(int i=1;i<=10000000;i++)d.push_back(i);for(int i=1;i<=10000000;i++)d.pop_back();for(int i=1;i<=10000000;i++)e.push_back(i);for(int i=1;i<=10000000;i++)e.pop_back();printf("My vector Cost Time:%d\n",clock()-tim);tim=clock();for(int i=1;i<=10000000;i++)A.push_back(i);for(int i=1;i<=10000000;i++)A.pop_back();for(int i=1;i<=10000000;i++)B.push_back(i);for(int i=1;i<=10000000;i++)B.pop_back();for(int i=1;i<=10000000;i++)C.push_back(i);for(int i=1;i<=10000000;i++)C.pop_back();for(int i=1;i<=10000000;i++)D.push_back(i);for(int i=1;i<=10000000;i++)D.pop_back();for(int i=1;i<=10000000;i++)E.push_back(i);for(int i=1;i<=10000000;i++)E.pop_back();printf("STL vector Cost Time:%d\n",clock()-tim);return 0; }效率實(shí)測(cè)
首先申明,在這份代碼中,手寫(xiě)vector的測(cè)試時(shí)間會(huì)偏大(但并不影響很多)
然后這里測(cè)的是5e7次push_back加上5e7次pop_back,單位毫秒(ms)
本機(jī)配置:Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.70GHz 64位操作系統(tǒng)
在不開(kāi)O2的情況下,手寫(xiě)的vector效率提高了很多誒,開(kāi)心
然而開(kāi)了O2,效率就被stl爆踩了咯
總結(jié)
如果不開(kāi)O2而且要用vector那么可以考慮手寫(xiě),開(kāi)O2的話那就大膽用了
然候malloc和free的使用非常方便,學(xué)會(huì)用這兩個(gè)東西也是很重要的(當(dāng)然也要謹(jǐn)慎使用其中的功能,否則出事情后果自負(fù)),可以通過(guò)這兩個(gè)函數(shù)解決文章開(kāi)頭我提到的問(wèn)題
總結(jié)
- 上一篇: 九省联考2018总结
- 下一篇: Prufer序列相关