手写vector

前言

近来做到一些题目,对于暴力有些卡空间,对于几个能拿分的subtask没个刚好都能过去,但是开的数组不一样,都开就MLE了,我就尝试着开同一个数组,卡的太紧,最后很多数据都MLE没分了,一气之下觉定学习动态开内存(顺便学习一下手写vector)

vector简介

vector?著名STL之一,又称动态数组,简直就是一个数组,有点像个栈
支持压入,弹出(push_back,pop_back)这个均摊O(1)
支持随机寻址
然后支持erase?删除中间一个数,可惜是O(n)的,然而跑的飞快(手写的vector里没写~逃~)
其它功能基本不用

实现方式

vector寻址O(1)是因为它的内存连续,一个vector由一个数组指针(后面代码中的Data,之后的变量也会用括号表示)、一个当前总可用存储大小(Len),已用存储大小(Size)
压入元素:如果存储的地方用完了,那么就把存储数组开大一倍
弹出元素:如果使用的存储占不到总存储的1/4那么就把存储数组减小一半

代码

下面这份代码里的class是首先的vector,后面是对速度的测验

#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;
}

效率实测

首先申明,在这份代码中,手写vector的测试时间会偏大(但并不影响很多)
然后这里测的是5e7次push_back加上5e7次pop_back,单位毫秒(ms)
本机配置:Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.70GHz 64位操作系统
在不开O2的情况下,手写的vector效率提高了很多诶,开心
这里写图片描述
然而开了O2,效率就被stl爆踩了咯
这里写图片描述

总结

如果不开O2而且要用vector那么可以考虑手写,开O2的话那就大胆用了
然候malloc和free的使用非常方便,学会用这两个东西也是很重要的(当然也要谨慎使用其中的功能,否则出事情后果自负),可以通过这两个函数解决文章开头我提到的问题

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhouyuheng2003/article/details/79965376
个人分类: OI STL
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭