vector

当我们需要一个动态数组来存数据时,都是使用的T * p = (T *)malloc(sizeof(T) * n);

众所周知,这个方法有严重的使用问题:

1) p指向的内存,其大小信息丢失了。

2) 数组没有赋初值

3) 数组没有办法自动扩大内存,所以越界问题一直令人头痛

4) 对数组的常用算法,都没有提供可重用的代码

 

所以,需要你们对动态数组进行封装

typedef struct

{

    T * pStart;

    //其它任何你认为需要额外增加的字段

} VECTOR;

 

提供如下形式的算法函数

1)  VECTOR Create(void); 创建一个空数组,里面元素个数为0

    VECTOR Create_n(int n);创建一个空数组,里面元素个数为n,每个元素都调用Init_T函数进行了赋初值。

    VECTOR Create_n(int n, T t);创建一个空数组,里面元素个数为n,每个元素都赋初值为t

    void   Destory(VECTOR *);销毁掉数组,回收内存

2)  int Size(VECTOR *);获得VECTOR里的元素个数

3)  T * Front(VECTOR *);获得VECTOR里的第一个元素的指针。请说明元素个数为0时,你的函数返回什么结果

    T * Back(VECTOR *);获得VECTOR里的最后一个元素的指针。请说明元素个数为0时,你的函数返回什么结果

4)  T * Begin(VECTOR *); T * End(VECTOR *);返回的2个指针构成半闭半开区间[begin, end)指示出数组里所有元素。

所谓半闭半开区间就是包括begin所指元素,但不包括end所指元素。半闭半开区间是数据使用上一个极重要的概念,因为它能表示空集合。配合下面的Next,你就可以在不管是否有元素的情况下都可简单地进行遍历了。

for (T * p = Begin(&v); p != End(&v); Next(&v, p))

{

    //Do Something Here!

}

    T * Next(VECTOR *, T *);假定传入的指针确保指向vector里的某个元素,给出它的下一个元素的指针。请说明已经指向最后一个元素时,你的函数返回什么结果。

    T * Prev(VECTOR *, T *);假定传入的指针确保指向vector里的某个元素,给出它的前一个元素的指针。请说明已经指向第一个元素时,你的函数返回什么结果。

5)  T * Find(VECTOR *, T t);搜索第一个值为t的元素,返回其指针。请说明没找到时,你的函数返回什么结果。

    int Count(VECTOR *, T t);计算值为t的元素的个数

6)  T * Insert(VECTOR *, T * pos, T t);pos所指元素及后面所有元素后移,将t插入到指针pos所指位置。返回新插入的元素的指针。如果插入元素将导致总元素个数超过原先分配的内存,必须重新分配内存进行扩容

    T * InsertRange(VECTOR *, T * pos, T * first, T * last);[first, last)所指区间中所有元素保持原顺序插入到pos所指元素之前。返回新插入的第一个元素的指针。如果插入元素将导致总元素个数超过原先分配的内存,必须重新分配内存进行扩容

    void Push_Back(VECTOR T t);在数组最后追加一个元素。

    T * Erase(VECTOR *, T * pos);删除指针pos所指元素,将后面的元素进行前移。返回被删除的元素的下一个元素的现在的指针。

    T * EraseRange(VECTOR *, T * first, T * last);删除指针[first, last)所指区间中的元素,将后面的元素进行前移。返回最后一个删除的元素的下一个元素的现在的指针。

    void Pop_Back(VECTOR * T t);删除数组的最后一个元素。

    void Clear(VECTOR *);清空所有元素。

    BOOL Remove(VECTOR *, T t);删除所有值为t的元素,剩下的元素进行前移以保持连续。返回“是否进行了删除”。

7)  void Assign(VECTOR * l, const VECTOR * r);使得l所指内存拥有和r完全相同的元素,而不是l.pr.p指向相同的地址。如果2者元素个不匹配,也许要重新分配内存分配。

    void Swap(VECTOR * l, const VECTOR * r);使得l拥有原来r的元素,r拥有l原来的元素。

VECTOR Create_byVector(const VECTOR * v)//创建和v具有完全相同元素的新VECTOR

VECTOR Create_byArray(const T * first, const T * last)//创建和[first, last)所指数组区间相同的元素的新VECTOR

 

8)      附加题:

    BOOL Empty(const VECTOR * v)//如果没有元素,返回TRUE,其它情况返回FLASE

    void Resize(VECTOR * v, int n)//如果n < Size(v),删除尾部Size(v) - n个元素,如果n > Size(v),在尾部追加n - Size(v)Init_T函数来初始化的新元素。

    void Resize_with_t(VECTOR * v, int n, T t)//如果n < Size(v),删除尾部Size(v) - n个元素,如果n > Size(v),在尾部追加n - Size(v)个值等于t的元素。

    T * At(VECTOR *, int n),返回数组里下标为n的元素的指针

    void  Assign_byArray(VECTOR * v, const T * first, const T * last)//使得v现在含有和[first, last)所指数组区间相同的元素

    BOOL Equal(const VECTOR * l, const VECTOR * r)//2VECTOR元素个数并且按顺序,每个元素都相同时,返回TRUE

BOOL Less(const VECTOR * l, const VECTOR * r)//按字典序进行比较,l < r时返回TRUE。字典序就是 a开始的所有单词 < b开头的所有单词;a在所有a开头的单词里最小;其它a开头的单词根据第二个字母起继续比较。

9)      提高题:

实现FindCountRemove操作的扩展。

    要能完成比如“Count(Vector *, XXXXXX);能计算所有值大于x的元素的个数”这样的通用问题。

 

10)   再提高题:

VECTORcreate函数创建后,因为分配了内存,所以必须用destory销毁的。而且每create一次,就得有且仅有一次对应的destory

如果有如下代码VECTOR v1 = CREATE_n(2);

              VECTOR v2 = CREATE_n(3);

              v2 = v1;

那么将导致v2create过程中分配的内存就泄漏了。

所以,问题是:如何能防止不小心的v2 = v1这类行为?

在你们的VECTOR代码里想办法完成,而不是指望使用VECTOR的人总不犯错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值