首页 > 其他分享 >STL-vector模拟实现

STL-vector模拟实现

时间:2024-02-27 22:35:00浏览次数:28  
标签:finish end STL start vector const 模拟 size

#pragma once
#include<assert.h>
#include<iostream>
using std::cout;
using std::endl;
using std::cin;

namespace test
{



    //#include<algorithm>
    //模板参数省略:1.作为时  2.作为类型名
    template <class T> //数组名:类型名:xx数组
    class vector
    {
    public:
        //成员类型 //也可以用内部类,但C++都是typedef居多,不喜欢内部类
        typedef T* iterator;
        typedef const T* const_iterator;
    private:
        //构造函数太多,初始化列表重复太多麻烦,直接给缺省参数方便//C++11
        iterator _start = nullptr; //数组头
        iterator _finish = nullptr;//数组有效数据尾的下一个(类似\0位置)
        iterator _end_of_storage = nullptr;//数组容量尾的下一个位置,有效空间的下一个位置

    public:
        //无参构造
        vector()
        {}
        //有参构造:开辟n个空间,1.数量 2开辟对象空间
        vector(size_t n, const T& val = T()) //缺省值为显式匿名构造,基本类型也支持
        {
            //_start = new T[n];
            //_finish = _start + n;
            //_end_of_storage = _start + n;
            //for (size_t i = 0; i < n; ++i)
            //{
            //    _start[i] = val;
            //}
            reserve(n);
            for (size_t i = 0; i < n; ++i)
            {
                push_back(val);
            }
        }
        //有参构造整型重载
        vector(int n, const T& val = T())

        {
            reserve(n);
            for (size_t i = 0; i < n; ++i)
            {
                push_back(val);
            }
        }
        //迭代器构造
        template <class InputIterator>
        vector(InputIterator first, InputIterator last)

        {
            //size_t sz = last - first;
            //_start = _finish = new T[sz];
            //while (first != last)
            //{
            //    *_finish = *first;
            //    ++first;
            //    ++_finish;
            //}
            //_end_of_storage = _start + sz;
            while (first != last)
            {
                push_back(*first);
                ++first;
            }
        }

        //C++11 initializer_list 构造
        vector(std::initializer_list<T> il) //常量不能引用
        {
            //两种写法
            //typename std::initializer_list<T>::iterator it = il.begin();
            //while (it != il.end())
            //{
            //    push_back(*it);
            //    ++it;
            //}

            for (auto e : il)
            {
                push_back(e);
            }
        }

        ~vector()
        {
            delete[] _start;
            _start = _finish = _end_of_storage = nullptr;
        }

        //拷贝构造
        vector(const vector<T>& v)
        {
            //_start = new T[v.capacity()];
            //for (size_t i = 0; i < v.size(); ++i)
            //{
            //    _start[i] = v._start[i];//这里可能用到重载=,从而实现深拷贝
            //}
            //_finish = _start + v.size();
            //_end_of_storage = _start + v.capacity();
            vector<T> tmp(v.begin(), v.end());
            swap(tmp);

        }

        void swap(vector<T>& v)
        {
            //不能使用赋值,死循环
            //_start = v._start;
            //_finish = v._finish;
            //_end_of_storage = v._end_of_storage;

            //由于是拷贝的空间,且不能使用赋值,故交换掉,原先的会释放掉,
            //旧空间已经交换给v了,v会在出了作用域后回收,所以不用手动释放
            std::swap(_start, v._start);
            std::swap(_finish, v._finish);
            std::swap(_end_of_storage, v._end_of_storage);
        }

        vector<T>& operator=(vector<T> v) //深拷贝
            //赋值运算符重载:操作数是vector<vector<>>,在非初始化时走这里,初始化时时拷贝构造
            //传值传参,v是拷贝,所以是再次调了拷贝构造,新空间了,所以相当于深拷贝
        {
            swap(v);
            return *this;
        }



        iterator begin()
        {
            return _start;
        }

        iterator end()
        {
            return _finish;
        }
        const_iterator begin() const
        {
            return _start;
        }
        const_iterator end() const
        {
            return _finish;
        }

        //Capacity
        size_t capacity() const
        {
            return _end_of_storage - _start;
        }
        size_t size() const
        {
            return _finish - _start;
        }
        bool empty() const
        {
            return _start == _finish;
        }
        T& operator[](size_t pos) //_start的类型是对象,所以返回迭代器
        {
            assert(pos < size());
            return _start[pos];
        }
        const T& operator[](size_t pos)const
        {
            assert(pos < size());
            return _start[pos];
        }

        void resize(size_t n, const T& val = T())
        {
            if (n > capacity())
            {
                reserve(n);
            }

            if (n > size())
            {
                while (_finish < _start + n)
                {
                    *_finish = val;
                    ++_finish;
                }
            }
            else
            {
                _finish = _start + n;
            }
        }

        void reserve(size_t n) //扩容
        {
            if (n > capacity())
            {
                size_t sz = size();
                T* tmp = new T[n];
                //memcpy()//可能会有浅拷贝
                for (size_t i = 0; i < sz; ++i)
                {
                    tmp[i] = _start[i];
                }
                delete[] _start;
                _start = tmp;
                _finish = tmp + sz; //必须放在后面,因为size与_finish有关
                _end_of_storage = tmp + n;
            }
        }

        void push_back(const T& x)//尾插
        {
            if (_finish == _end_of_storage)
            {
                size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
                reserve(newCapacity);
            }
            *_finish = x;
            ++_finish;
        }

        void pop_back() //尾删
        {
            //if (empty())
            //{
            //    return;
            //}
            assert(!empty());
            --_finish;
        }

        iterator insert(iterator pos, const T& val)//插入//返回原来插入的位置
        {
            assert(pos >= _start);
            assert(pos <= _finish);
            if (_finish == _end_of_storage)//reserve后迭代器失效
            {
                size_t len = _end_of_storage - _start;
                size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
                reserve(newCapacity);

                pos = _start + len;                // 扩容会导致pos迭代器失效,需要更新处理一下
            }
            iterator end = _finish; //减少用end
            while (end >= pos)
            {
                *(end + 1) = *end;
                --end;
            }
            *pos = val;
            ++_finish;
            return pos; //防止迭代器可能因为扩容而失效,因此将迭代器作为返回值

        }
        iterator erase(iterator pos)//删除 //返回删除的下一个位置
        {
            assert(pos >= _start);
            assert(pos < _finish);
            iterator begin = pos + 1; //增加用begin
            while (begin != _finish)
            {
                *(begin - 1) = *begin;
                ++begin;
            }

            --_finish;
            return pos;
        }
    };

    //测试用例
    class Solution {
    public:
        vector<vector<int>> generate(int numRows) {
            vector<vector<int>> vv;
            vv.resize(numRows, vector<int>());

            for (size_t i = 0; i < vv.size(); ++i)
            {
                vv[i].resize(i + 1, 0);
                vv[i][0] = vv[i][vv[i].size() - 1] = 1;

                for (size_t j = 0; j < vv[i].size(); ++j)
                {
                    if (vv[i][j] == 0)
                    {
                        vv[i][j] = vv[i - 1][j - 1] + vv[i - 1][j];
                    }
                }
            }
            return vv;
        }
    };

    void test_vector4()
    {
        using namespace std;
        vector<vector<int>> vv = Solution().generate(3);
        for (size_t i = 0; i < vv.size(); ++i)
        {
            for (size_t j = 0; j < vv[i].size(); ++j)
            {
                cout << vv[i][j] << " ";
            }
            cout << endl;
        }
        cout << endl;

        vector<vector<int>> v3 = vv;//初始化=是拷贝构造 ,深拷贝过程中=是重载
        for (size_t i = 0; i < v3.size(); ++i)
        {
            for (size_t j = 0; j < v3[i].size(); ++j)
            {
                cout << v3[i][j] << " ";
            }
            cout << endl;
        }

        vector<int> v1;
        v1.resize(3, 1);
        vector<int> v2 = v1; //初始化=是拷贝构造
        for (auto e : v2)
        {
            cout << e << " ";
        }
    }

    void test_vector5()
    {
        vector<int> v = { 1,2,3,4,5 }; //initializer_list 初始化

    }



}

 

标签:finish,end,STL,start,vector,const,模拟,size
From: https://www.cnblogs.com/DSCL-ing/p/18038570

相关文章

  • STL-list模拟实现
    #pragmaonce#include"16my_Itetator.h"//测试用#include<iostream>//测试用usingstd::cout;usingstd::endl;usingstd::cin;namespacetest{//struct默认权限是public,一般也不会加权限,class才会(需要封装时使用class)//结点使用struct的好处是开放结点,......
  • STL-stack模拟实现
    #pragmaonce#include<assert.h>#include<list>#include<vector>#include<deque>#include<iostream>usingstd::cout;usingstd::endl;usingstd::cin;namespacetest{//template<classT,classContainers=std::vector&......
  • STL-queue模拟实现
    #include<list>#include<assert.h>#include<deque>#include<iostream>usingstd::cout;usingstd::endl;usingstd::cin;namespacetest{//template<classT,classContainers=std::list<T>>template<classT,c......
  • 2024.2.27模拟赛T2题解
    题目有一个神奇的结论\(\foralla<b<c,a\oplusc>min(a\oplusb,b\oplusc)\)然后就可以写出\(n^2\)dp,再用TRIE树优化即可code#include<bits/stdc++.h>usingnamespacestd;#defineN200005#defineintlonglongintn,k1,k2;inta[N],fl[2];constintm......
  • C++ STL 容器 list类型
    C++STL容器list类型list对于异常支持很好,要么成功,要么不会发生什么事情以下是std::list在异常处理方面表现良好的几个原因:动态内存管理:std::list使用动态内存分配来存储元素,这意味着它会在需要时自动分配内存,并在不再需要时释放内存。这种自动管理可以减少内存泄漏和悬......
  • C++ STL 容器-Deque
    C++STL容器-Dequestd::deque(双端队列)是C++标准模板库(STL)中的一个容器,它支持在序列的两端快速插入和删除元素。与std::vector和std::list等其他序列容器相比,std::deque在某些特定场景下具有独特的优势。元素的访问和迭代比vector慢,迭代器不是普通的指针。以下是std::deque的一......
  • 安卓模拟器
    安卓模拟器种类雷电夜神逍遥雷神模拟器本质安卓模拟器的本质是一台小型的虚拟机以雷电9模拟器为例在雷电9模拟器的安装目录下有一个vms文件,里面存储着虚拟机的信息 随便点开一个虚拟机分析文件目录下的三个vmdk文件,与安卓手机的文件系统一一对应!data存储用户......
  • Qt QVector和vector以及QMap和map的遍历性能对比
    使用Qt中的容器给C++开发带来很大的便利,而且QVector和QMap等容器扩展的一些成员函数也是很方便的。但是Qt的这些容器和STL库的容器比,效率到底怎么样?我就写了几个简单的遍历的例子,测试了QVector、vector等容器的那些方法效率更高。测试环境:系统:windows10编译器:MingGWmingw......
  • Qt QVector、QList、QSet和QMap:性能与用途比较
    Qt提供了多种容器类,用于存储和管理数据。其中,QVector、QList、QSet和QMap是最常用的几种。这些容器类在性能和用途方面存在一些差异,选择合适的容器对于提高应用程序的效率和正确性至关重要。下面我们将从以下几个方面对这四种容器进行比较:1.存储方式QVector:动态数组,元素在......
  • C++ STL 容器-Vector类型
    C++STL容器-Vector类型std::vector是C++标准库中的一个动态数组容器,它提供了随机访问迭代器,因此你可以像使用普通数组一样使用vector。vector容器可以动态地增长和缩小,这意味着你可以在不预先指定数组大小的情况下向其中添加或删除元素。特点动态大小:vector的大小可以在运......