zoukankan      html  css  js  c++  java
  • 手写的奇怪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>;
    
  • 相关阅读:
    【GoLand】分享项目到Github平台
    【Git】实用教程
    【Go】Mac系统下安装GoLand 及 环境配置
    CF 901C Bipartite Segments
    CF 811E Vladik and Entertaining Flags
    Luogu P6300 悔改
    Luogu P3943 星空
    CSP2020 | T4
    NOIP2017 | D2T3
    Luogu P6852 Mex
  • 原文地址:https://www.cnblogs.com/Yuhuger/p/10546728.html
Copyright © 2011-2022 走看看