C++ はベクトル動的配列の簡易版を実現します

1. アイデア

(1) 最初に配列の初期要素数と値を入力すると、プログラムは要素数の 2 倍のスペースを適用し、残りの 2 倍のスペースは要素の挿入に使用されます。

(2) 要素を挿入するときは、まずスペースが残っているかどうかを確認し、スペースがある場合は挿入し、スペースがない場合は展開します。

(3) このバージョンの拡張戦略は、残りのスペースが十分でない場合、現在の総容量の 2 倍に従って拡張されます。

(4) プログラムの堅牢性を実現するために、データの挿入または削除時に、入力された添字が要素の添字範囲内にない場合は、ユーザーに添字の再入力を求めるプロンプトを表示する必要があります。

(5) Push_back 関数を実行すると、プログラムは現在の容量と同じ数の要素を挿入し、容量を確実に拡張します。

(6) ほとんどの機能はクラスとオブジェクトの形式で実装する必要があります。

2. コードの実装

#include  <iostream>
#include  <cstdlib>
#include  <exception>
using  namespace  std;

template<typename  T>   // 函数模板,语法糖
class  dyArray
{
private:
    //member  of  data
    T  *  _pData  =  nullptr;//指针,指向heap中的内存空间首地址
    size_t  _nSize  =  0;//数组中元素个数
    size_t  _nCapacity  =  0;//容量
public:
    //member  of  function
    //ctor
    dyArray(size_t  n=10);
    //ctor  overload  n为申请空间中的元素个数  val为数组中各元素的初始值
    dyArray(size_t  n,const  T  &  val);
    //copy  ctor
    dyArray(const  dyArray  &  obj);
    //dtor
    ~dyArray();
private:
    //memory  allocate  分配内存空间
    void  memset(size_t  n)
    {
        release();
        //invoke  operator  operator  new
        if(n  >  0)
        {
            _pData  =  new  T[n];
        }
    }
    //dump  memory  释放内存空间
    void  release()
    {
        if(_pData)
        {
            delete  []  _pData;
            _pData  =  nullptr;
        }
    }
public:
    //member  of  function
    //overload  operator  []
    //nidx为下标索引
    T  &  operator[](size_t  nidx)
    {
        return  _pData[nidx];
    }
    const  T  &  operator[](size_t  nidx)const
    {
        return  _pData[nidx];
    }
    //overload  operator=
    //rhs  source  of  array
    dyArray<T>  &  operator=(const  dyArray<T>  &  rhs);
public:
    //get  begin  &  end
    T  *  begin()
    {
        return  _pData;
    }
    const  T  *  begin()const
    {
        return  _pData;
    }
    T  *  end()
    {
        return  _pData  +  _nSize;
    }
    const  T  *  end()const
    {
        return  _pData  +  _nSize;
    }
    //get  size  获取数组中元素个数
    size_t  size()const
    {
        return  _nSize;
    }
    //get  capacity  获取数组中容量个数
    size_t  capacity()const
    {
        return  _nCapacity;
    }
    //append  在尾部增加一个数据
    void  push_back(const  T  &  val);
    //delete  at  删除指定位置(nidx)的元素
    bool  deleteAt(size_t  nidx);
    void  removeAll();//移除所有的元素
    //insert  value  在指定位置(nidx)后面插入一个数据val
    bool  insert(size_t  nidx,const  T  &  val);
public:
    //conversion  function
    operator  T*()
    {
        return  _pData;
    }
    operator  const  T*()const
    {
        return  _pData;
    }
private:
    //扩容  当战备池用完后,需要扩容时,进行2倍扩容
    void  expansion();
};
template<typename  T>
// 构造函数
dyArray<T>::dyArray(size_t  n)
{
    // 分配空间
    dyArray::memset(n*2);
    // 如果n大于0,则正常分配
    if(_pData!=nullptr)
    {
        _nSize=n;
        _nCapacity=2*n;
    }
}
template<typename  T>
dyArray<T>::dyArray(size_t  n,const  T  &  val)
{
    // 分配空间
    memset(n*2);
    // 如果n大于0,则正常分配
    if(_pData!=nullptr)
    {
        _nSize=n;
        _nCapacity=2*n;
        // 赋值
        for(int i=0;i<n;i++)
        {
            _pData[i]=val;
        }
    }
}
template<typename  T>
dyArray<T>::dyArray(const  dyArray  &  obj)
{
    _pData=obj._pData;
    _nSize=obj._nSize;
    _nCapacity=obj._nCapacity;
}

// 析构函数
template<typename  T>
dyArray<T>::~dyArray()
{
    delete [] _pData;
    _pData=nullptr;
}

// 在尾部插入元素
template<typename  T>
void dyArray<T>::push_back(const  T  &  val)
{
    // 检查战备池是否用完,用完则扩容
    if(_nSize==_nCapacity)
    {
        expansion();
    }
    _pData[_nSize]=val;
    _nSize++;
}

// 删除nidx位置的元素
template<typename  T>
bool dyArray<T>::deleteAt(size_t  nidx)
{
    if(nidx<0 || nidx>=_nSize) return false;
    for(int i=nidx;i<_nSize-1;i++)
    {
        _pData[i]=_pData[i+1];
    }
    _nSize--;
    return true;
}

// 移除所有的元素
template<typename  T>
void dyArray<T>::removeAll()
{
    _nSize=0;
}

// 在指定位置nidx后面插入一个数据val
template<typename  T>
bool dyArray<T>::insert(size_t  nidx,const  T  &  val)
{
    if(nidx<0 || nidx>=_nSize) return false;
    // 检查战备池是否用完
    if(_nSize==_nCapacity)
    {
        expansion();    // 战备池用完,进行扩容
    }
    for(int i=_nSize;i>nidx+1;i--)
    {
        _pData[i]=_pData[i-1];
    }
    _pData[nidx+1]=val;
    _nSize++;
    return true;
}

// 扩容
template<typename T>
void dyArray<T>::expansion()
{
    // 申请一个新空间
    size_t newCapacity=2*_nCapacity;
    T* newPointer=new T[newCapacity];
    // 拷贝旧数据
    //memmove(newPointer,_pData,_nSize * sizeof(T));
    // 拷贝旧数据也可以这样写
    for(int i=0;i<_nSize;i++)
    {
        newPointer[i]=_pData[i];
    }
    // 释放旧空间
    release();
    // 设置成员变量
    _pData=newPointer;
    _nCapacity=newCapacity;
}

template<typename  T>
void  display(T  *  first,T  *  last)
{
    T  *  start  =  first;
    while(start  !=  last)
    {
        cout<<*start<<"  ";
        start++;
    }
    cout<<endl;
}

int  main()
{
    int  n  =  10;
    int  val  =  0;
    int  val1  =  0;
    cout<<"输入起始元素个数和初始值:"<<endl;
    cin>>n>>val;    // 输入起始元素个数和初始值
    size_t  npos  =  0; // 最长的无符号整数
    cout<<"输入插入数据的下标和要插入的值,在此后进行插入:"<<endl;
    cin>>npos>>val1;    // 输入插入位置和插入的值,在此后进行插入
    dyArray<int>  ar(n,val);
    int  *  first  =  ar.begin();
    int  *  last  =  ar.end();
    cout<<"输出插入元素前的状态:"<<endl;
    display(first,last);
    while(!ar.insert(npos,val1))
    {
        cout<<"插入失败!请重新输入要插入的位置:"<<endl;
        cin>>npos;
    }
    first  =  ar.begin();
    last  =  ar.end();
    cout<<"输出插入元素后的状态:"<<endl;
    display(first,last);
    size_t  nc  =  ar.capacity();
    for(size_t  i=0; i<nc; ++i)
    {
        ar.push_back(i);
    }
    cout<<"输出push_back后的元素个数和容量:"<<endl;
    cout<<ar.size()<<"  "<<ar.capacity()<<endl;
    first  =  ar.begin();
    last  =  ar.end();
    cout<<"输出push_back后的状态:"<<endl;
    display(first,last);
    cout<<"输入要删除的元素下标:"<<endl;
    cin>>npos;
    while(!ar.deleteAt(npos))
    {
        cout<<"删除失败!请重新输入要删除的元素下标:"<<endl;
        cin>>npos;
    }
    ar.deleteAt(npos);
    cout<<"输出删除指定下标元素后的状态:"<<endl;
    first=ar.begin();
    last=ar.end();
    display(first,last);
    cout<<"输出移除所有值后的元素个数和容量:"<<endl;
    ar.removeAll();
    cout<<ar.size()<<" "<<ar.capacity()<<endl;
    return  0;
}

3. プログラム実行結果

 

おすすめ

転載: blog.csdn.net/KK_2018/article/details/129328700