动态数组(C++)

时间:2022-05-26
本文章向大家介绍动态数组(C++),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
#include<iostream>
#include <sstream>
#include<iterator>
#include<algorithm>

using namespace std;

// 重写copy代码
template<class iterator>
void copy(iterator start, iterator end, iterator to) {
    // 从start复制到[to, to+end-start)
    while (start != end)
        *(to++) = *(start++);
}

template<class T>
class linearList {
public:
    virtual ~linearList() = default;;

    virtual bool empty() const = 0; /* 返回true,当且仅当线性表为空 */
    virtual int size() const = 0; /* 返回线性表的元素个数 */
    virtual T &get(int theIndex) const = 0; /* 返回索引为theIndex的元素 */
    virtual int indexOf(const T &theElement) const = 0; /* 返回元素theElement第一次出现时的索引 */
    virtual void erase(int theIndex) = 0; /* 删除索引为theIndex的元素 */
    virtual void insert(int theIndex, const T &theElement) = 0;/* 把theElement插入线性表中索引为theIndex的位置上 */
    virtual void output(ostream &out) const = 0;/*把线性表插入输出流*/
};

class illegalParameterValue {
public:
    illegalParameterValue() : message("Illegal parameter value") {}

    explicit illegalParameterValue(char *theMessage) {
        message = theMessage;
    }

    explicit illegalParameterValue(const string &theMessage) {
        message = theMessage;
        cout << message << endl;
    }

    void outputMessage() { cout << message << endl; }

private:
    string message;
};

/* 改变一个一位数组的长度*/
template<class T>
void changeLength1D(T *&a, int oldLength, int newLength) {
    if (newLength < 0)  /* 如果新表长小于0 */
        throw illegalParameterValue("new length muse be >= 0"); /* 抛出异常*/
    T *temp = new T[newLength]; /* 申请新的数组空间*/
    int number = min(oldLength, newLength); /*过的原来数组长度和现在数组长度中较小者*/
    copy(a, a + number, temp); /* 将原数组中的数据放到新的数组中*/
    delete[] a; /* 删除原来数组的空间*/
    a = temp; /*将新数组空间的地址给原来的数组名*/
}

/* 类arrayList定义
 * 定义抽象类linearList的派生类arrayList
 * 来实现抽象数据类型linearList
*/
template<class T>
class arrayList : public linearList<T> {
public:
    /* 构造函数,复制构造函数和构析函数 */
    arrayList(int initialCapacity = 10);

    arrayList(const arrayList<T> &);

    ~arrayList() { delete[]element; }

    /* ADT方法 */
    bool empty() const { return listSize == 0; }

    int size() const { return listSize; }

    T &get(int theIndex) const;

    int indexOf(const T &theElement) const;

    void erase(int theIndex);

    void insert(int theIndex, const T &theElement);

    void output(ostream &out) const;

    int capacity() const { return arrayLength; }

protected:
    void checkIndex(int theIndex) const;

    T *element; /* 存储线性表元素的一维数组 */
    int arrayLength; /* 一维数组的容量 */
    int listSize; /* 线性表的元素个数 */
};

template<class T>
void arrayList<T>::checkIndex(int theIndex) const {
    if (theIndex < 0 || theIndex >= listSize) {
        ostringstream s;
        s << "index = " << theIndex << " size = " << listSize;
        throw illegalParameterValue(s.str());
    }
}

template<class T>
T &arrayList<T>::get(int theIndex) const {
    // 返回索引为theIndex的元素
    // 若此元素不存在,则抛出异常
    checkIndex(theIndex);
    return element[theIndex];
}

template<class T>
int arrayList<T>::indexOf(const T &theElement) const {
    // 返回元素theElement第一次出现时的索引
    // 若该元素不存在,则返回-1
    // 查找元素theElement
    int theIndex = (int) (find(element, element + listSize, theElement) - element);
    // 确定theElement是否找到
    if (theIndex == listSize)
        // 没有找到
        return -1;
    else
        return theIndex;
}

template<class T>
void arrayList<T>::erase(int theIndex) {
    // 删除其索引为theIndex的元素
    // 如果该元素不存在,则抛出illegal
    checkIndex(theIndex);
    // 有效索引,移动其索引大于theIndex的元素
    copy(element + theIndex + 1, element + listSize, element + theIndex);
    element[--listSize].~T(); // 调用构析函数
}

// arrayList的构造函数
template<class T>
arrayList<T>::arrayList(int initialCapacity) {
    // 构造函数
    if (initialCapacity < 1) {
        ostringstream s;
        s << "Initial capacity = " << initialCapacity << " Must be > 0";
        throw illegalParameterValue(s.str());
    }
    arrayLength = initialCapacity;
    element = new T[arrayLength];
    listSize = 0;
}

template<class T>
arrayList<T>::arrayList(const arrayList<T> &theList) {
    // 复制构造函数
    arrayLength = theList.arrayLength;
    listSize = theList.listSize;
    element = new T[arrayLength];
    copy(theList.element, theList.element + listSize, element);
}

template<class T>
void arrayList<T>::insert(int theIndex, const T &theElement) {
    // 在索引theIndex处插入元素theElement
    if (theIndex < 0 || theIndex > listSize) {
        // 无效索引
        ostringstream s;
        s << "index = " << theIndex << " size = " << listSize;
        throw illegalParameterValue(s.str());
    }
    // 有效索引,确认数组是否已满
    if (listSize == arrayLength) {
        // 数组空间已满,数组长度倍增
        changeLength1D(element, arrayLength, arrayLength * 2);
        arrayLength *= 2;
    }
    // 把元素向右移动一个位置
    copy_backward(element + theIndex, element + listSize, element + listSize + 1);
    element[theIndex] = theElement;
    ++listSize;
}

// 把一个线性表插入输出流
template<class T>
void arrayList<T>::output(ostream &out) const {
    copy(element, element + listSize, ostream_iterator<T>(cout, " "));
}

// 重载<<
template<class T>
ostream &operator<<(ostream &out, const arrayList<T> &x) {
    x.output(out);
    return out;
}

int main() {
    auto *array1 = new arrayList<int>(100);
    arrayList<double> y(100);
    cout << *array1 << endl;
    cout << y << endl;
    return 0;

}

原文地址:https://www.cnblogs.com/Reion/p/16315151.html