手写的奇怪vector
手写了一个动态申请内存的数组,更准确的说是一个本来应该是块链,最后由于太耗时间了变成数组的东西。
由于太懒了,编译需要用c++11或以上。
两个参数分别是元素类型和块大小S。申请内存以块为单位,很明显如果块大小是\(O(n)\)那么就是数组,如果块大小是\(O(1)\)那么就是链表。
各种操作的复杂度跟数组没啥区别,有可能乘上一个\(O(n/S)\),毕竟我太懒了。
重载了许多构造函数,重载了迭代器,应该可以支持大部分stl算法,冒号遍历应该也没有问题。
结果慢的飞起,被vector卡爆了,目前还不知有个毛用。
有bug吗?我也不知道,暂且可以过一些题。
曾经有过内存泄漏的bug,不过现在应该不会了。
namespace container{
template<class T,size_t BLOCK_SIZE>
class myarray{
struct period{
T* a;
period* ne=NULL;
period(){
//slow but safe
a=new T[BLOCK_SIZE]();
}
period(const T &v){
a=new T[BLOCK_SIZE](v);
}
~period(){
delete []a;
}
};
period *Be;
size_t Sz;
class iterator{
period *ip;
size_t pos;
myarray *po;
public:
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef ptrdiff_t difference_type;
iterator():ip(nullptr),pos(0),po(nullptr){
}
iterator(const iterator &it){
(*this)=it;
}
iterator(period * const &ip,const size_t &pos,myarray * const &po):ip(ip),pos(pos),po(po){
}
bool operator !=(const iterator &it) const{
return ip!=it.ip||pos!=it.pos;
}
bool operator ==(const iterator &it) const{
return ip==it.ip&&pos==it.pos;
}
iterator operator ++(){
if (++pos==BLOCK_SIZE&&ip->ne!=NULL){
ip=ip->ne;
pos=0;
}
return *this;
}
const iterator operator ++(int){
iterator tmp(*this);
if (++pos==BLOCK_SIZE&&ip->ne!=NULL){
ip=ip->ne;
pos=0;
}
return tmp;
}
iterator operator --(){
if (pos){
--pos;
return (*this);
}
period *tBe=po->Be;
while (tBe->ne!=ip) tBe=tBe->ne;
ip=tBe;
pos=BLOCK_SIZE-1;
return (*this);
}
const iterator operator --(int){
iterator tmp(*this);
if (pos){
--pos;
return tmp;
}
period *tBe=po->Be;
while (tBe->ne!=ip) tBe=tBe->ne;
ip=tBe;
pos=BLOCK_SIZE-1;
return tmp;
}
iterator operator +(const size_t &len) const{
//ip!=NULL BUG
if (BLOCK_SIZE>pos+len) return iterator(ip,pos+len,po);
size_t tmp=len-(BLOCK_SIZE-1-pos);
if (ip->ne==NULL) return iterator(ip,BLOCK_SIZE,po);
period *tip=ip->ne;
while (tmp>BLOCK_SIZE){
if (tip->ne==NULL) return iterator(tip,BLOCK_SIZE,po);
tip=tip->ne;
tmp-=BLOCK_SIZE;
}
return iterator(tip,tmp-1,po);
}
iterator operator +=(const size_t &len){
return ((*this)=(*this)+len);
}
size_t operator -(const iterator &it) const{
//only
if (ip==it.ip) return pos-it.pos;
period *tmp=it.ip->ne;
size_t ret=BLOCK_SIZE-it.pos;
while (tmp!=ip){
ret+=BLOCK_SIZE;
tmp=tmp->ne;
}
return ret+pos;
}
iterator operator -(const size_t &len) const{
return (po->begin()+((*this)-(po->begin())-len));
}
iterator operator -=(const size_t &len){
return ((*this)=(*this)-len);
}
bool operator <(const iterator &it) const{
//same father
return ((*this)-po->begin())<(it-(po->begin()));
}
bool operator <=(const iterator &it) const{
//same father
return ((*this)-po->begin())<=(it-(po->begin()));
}
T & operator *() const{
return ip->a[pos];
}
};
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef size_t size_type;
myarray(){
Be=NULL;
Sz=0;
}
myarray(const size_t &sz){
construct(sz);
}
myarray(const size_t &sz,const T &v){
construct(sz,v);
}
~myarray(){
myfree(Be);
}
myarray(const myarray &rhs){
if (this==&rhs) return;
construct(rhs.size());
auto j=begin();
for (auto it=rhs.begin(); it!=rhs.end(); ++it) *(j++)=(*it);
}
myarray(const initializer_list<T> &args){
construct(args.size());
auto j=begin();
for (auto it=args.begin(); it!=args.end(); ++it) *(j++)=(*it);
}
myarray& operator =(const myarray &rhs){
if (this==&rhs) return (*this);
myfree(Be);
construct(rhs.size());
auto j=begin();
for (auto it=rhs.begin(); it!=rhs.end(); ++it) *(j++)=(*it);
return *this;
}
void myfree(period * const &Be){
period *tBe=Be,*tmp;
while (tBe!=NULL){
tmp=tBe->ne;
delete tBe;
tBe=tmp;
}
}
void construct(const size_t &sz){
Be=new period();//slow but safe
Sz=sz;
size_t tSz=sz;
period *tBe=Be;
while (tSz>BLOCK_SIZE){
tBe=(tBe->ne=new period);
tSz-=BLOCK_SIZE;
}
}
void construct(const size_t &sz,const T &v){
Be=new period(v);
Sz=sz;
size_t tSz=sz;
period *tBe=Be;
while (tSz>BLOCK_SIZE){
tBe=(tBe->ne=new period);
tSz-=BLOCK_SIZE;
}
}
iterator begin() const{
return iterator(Be,0,(myarray*)this);
}
iterator end() const{
//Slow And Dangerous
if (Be==NULL) return iterator(NULL,0,(myarray*)this);
period *tBe=Be;
while (tBe->ne!=NULL) tBe=tBe->ne;
return iterator(tBe,((int)Sz-1)%(int)BLOCK_SIZE+1,(myarray*)this);
}
void push_back(const T &v){
if (Be==NULL){
Be=new period;
Be->a[Sz++]=v;
return;
}
period *tBe=Be;
while (tBe->ne!=NULL) tBe=tBe->ne;
size_t tSz=(Sz++)%BLOCK_SIZE;
if (tSz==0) tBe=(tBe->ne=new period);
tBe->a[tSz]=v;
}
void pop_back(){
if ((--Sz)%BLOCK_SIZE) return;
if (Sz==0){
delete Be;
Be=NULL;
return;
}
period *tBe=Be;
while (tBe->ne->ne!=NULL) tBe=tBe->ne;
delete tBe->ne;
tBe->ne=NULL;
}
T& operator [](const size_t &pos) const{
size_t tpos=pos;
for (period* i=Be; i!=NULL; i=i->ne)
if (tpos<BLOCK_SIZE) return i->a[tpos];
else tpos-=BLOCK_SIZE;
throw;
}
T& front() const{
//unusual
return Be->a[0];
}
T& back() const{
return *(--end());
}
size_t size() const{
return Sz;
}
bool empty() const{
return Sz==0;
}
void swap(myarray &arr){
std::swap(Be,arr.Be);
std::swap(Sz,arr.Sz);
}
template<class U>
struct iterator_traits{
typedef typename U::value_type value_type;
typedef typename U::iterator_category iterator_category;
typedef typename U::difference_type difference_type;
typedef typename U::pointer pointer;
typedef typename U::reference reference;
};
};
}
template<class T=int,size_t BLOCK_SIZE=32>
using arr=container::myarray<T,BLOCK_SIZE>;