问题描述

实现一个能够实现自动扩容ArrayList类的封装(不使用C++容器),主要至少具有增加、删除、求长的功能

参考解答

ArrayList.h文件

#ifndef ARRAYLIST_H
#define ARRAYLIST_Hclass ArrayList
{public:ArrayList();ArrayList(const int data[], int len);~ArrayList();int length()const;int insert(int idx, int num);int remove(int idx);void display()const;
private:int* arr;int len;int capacity;
};#endif // !ARRAYLIST_H

ArrayList.cpp文件

#include "ArrayList.h"#include <iostream>  // 1、如果不引入一个标准库的话,它会说NULL未定义;2、输出错误信息using namespace std;/**    功能:*     ArrayList类的缺省构造函数*  参数:*     void*   返回值:*        无*  作者:*     Excious**/
ArrayList::ArrayList()
{this->arr = NULL;this->len = 0;this->capacity = 0;
}/**    功能:*     用数组及其长度构造一个ArrayList对象* 参数:*     data    in    数据数组的首地址*     len     in    数据数组的长度(元素个数)*  返回值:*        无*  说明:*     如果内存不够,可能会出现构建对象失败的情况,控制台将输出“【创建对象时,动态申请空间失败】”*    作者:*     Excious**/
ArrayList::ArrayList(const int data[], int len)
{if (len <= 0){this->arr = NULL;this->len = 0;this->capacity = 0;}else{this->arr = new int[len];if (NULL == arr){cout << "【创建对象时,动态申请空间失败】" << endl;this->len = 0;this->capacity = 0;return;}else{this->len = len;this->capacity = len;memcpy(arr, data, len * sizeof(int));  // 拷贝内存,据说只要内存上没有重叠部分就能很高效完成}}
}/**    功能:*     ArrayList类的析构函数*    参数:*     void*   返回值:*        无*  作者:*     Excious**/
ArrayList::~ArrayList()
{if (this->arr != NULL){delete[] this->arr;}
}/**    功能:*     返回当前ArrayList对象中的元素个数*  参数:*     void*   返回值:*        当前ArrayList对象中的元素个数*    作者:*     Excious**/
int ArrayList::length()const
{return this->len;
}/**    功能:*     在当前ArrayList对象的中的数组下标为idx的元素前插入元素num*   参数:*     idx     in      数组中插入数据的位置*     num     in      要插入的元素* 返回值:*         0    插入元素成功*       -1    扩容失败,插入失败(控制台输出信息“【创建临时数组时,动态申请空间失败】”)*       -2    插入元素位置非法,插入失败(控制台输出信息“【插入数据的位置不合法】”)*    说明:*     扩容后插入使用了函数memcpy,原理是拷贝内存里的内容,据说在拷贝和复制的部分有内存重叠时会出问题*       不过我这里既然是动态分配空间,只要不是自己复制自己的部分内容,是不会出现内存重叠的情况的* 作者:*     Excious**/
int ArrayList::insert(int idx, int num)
{// 检验插入数据的合法性if (idx < 0 || idx >= this->len){cout << "【插入数据的位置不合法】" << endl;return -2;}// 检查空间容量是否需要扩容(按照2倍扩容)if (this->capacity == this->len){this->capacity = this->len * 2;int* tmp = new int[this->capacity];if (NULL == tmp){cout << "【创建临时数组时,动态申请空间失败】" << endl;;this->capacity /= 2;return -1;}else{memcpy(tmp, this->arr, idx * sizeof(int));tmp[idx] = num;memcpy(tmp + idx + 1, this->arr + idx, (this->len - idx) * sizeof(int));delete[] this->arr;this->arr = tmp;++this->len;}}else{for (int i = this->len - 1; i >= idx; --i)  // 元素批量后移{this->arr[i + 1] = this->arr[i];}this->arr[idx] = num;++this->len;}return 0;
}/**    功能:*     删除当前ArrayList对象的数组中下标为idx的元素*   参数:*     idx     in      要删除的元素在数组中的下标*  返回值:*         0    删除元素成功*       -2    删除元素位置非法,插入失败(控制台输出信息“【插入数据的位置不合法】”)*    作者:*     Excious**/
int ArrayList::remove(int idx)
{// 检验删除数据的合法性if (idx < 0 || idx >= this->len){cout << "【删除数据的位置不合法】" << endl;return -2;}for (int i = idx + 1; i < len; ++i){this->arr[i - 1] = this->arr[i];}--this->len;return 0;
}/**    功能:*     打印当前ArrayList对象的元素* 参数:*     void*   返回值:*        void*   作者:*     Excious**/
void ArrayList::display() const
{int counter = 0;for (int i = 0; i < this->len; ++i){if (counter != 0)  // 控制行首、行尾无空格(空格在元素之间){cout << ' ';}cout << this->arr[i];++counter;if (0 == counter % 10)  // 控制一行10个元素{cout << endl;counter = 0;}}
}

main.cpp文件

#include "ArrayList.h"
#include <iostream>using namespace std;int main()
{int data1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int data2[] = { 0 };ArrayList al_default;ArrayList al_data1 = ArrayList(data1, sizeof(data1) / sizeof(int));ArrayList al_data2 = ArrayList(data2, sizeof(data2) / sizeof(int));cout << "缺省的数组:" << endl;al_default.display();cout << "\n根据data1构造的数组:" << endl;al_data1.display();cout << "\n根据data2构造的数组:" << endl;al_data2.display();cout << "\n\n给al_data1在下标为6的元素前插入数据5:" << endl;al_data1.insert(6, 5);al_data1.display();cout << "\n给al_data1在下标为0的元素前插入数据-1:" << endl;al_data1.insert(0, -1);al_data1.display();cout << "\n\n给al_data2在下标为0的元素前插入数据-1:" << endl;al_data2.insert(0, -1);al_data2.display();cout << "\n给al_data2在下标为1的元素前插入数据2:" << endl;al_data2.insert(1, 2);al_data2.display();cout << "\n给al_data2在下标为2的元素前插入数据3:" << endl;al_data2.insert(2, 3);al_data2.display();cout << "\n给al_data2在下标为3的元素前插入数据4:" << endl;al_data2.insert(3, 4);al_data2.display();cout << "\n给al_data2在下标为-1的元素前插入数据4:" << endl;al_data2.insert(-1, 4);al_data2.display();cout << "\n给al_data2在下标为500的元素前插入数据4:" << endl;al_data2.insert(500, 4);al_data2.display();cout << "\n\n删除al_data2中下标为-1的元素:" << endl;al_data2.remove(-1);al_data2.display();cout << "\n删除al_data2中下标为5的元素:" << endl;al_data2.remove(5);al_data2.display();cout << "\n删除al_data2中下标为2的元素:" << endl;al_data2.remove(2);al_data2.display();cout << "\n删除al_data2中下标为0的元素:" << endl;al_data2.remove(0);al_data2.display();cout << "\n删除al_data2中下标为0的元素:" << endl;al_data2.remove(0);al_data2.display();cout << "\n删除al_data2中下标为0的元素:" << endl;al_data2.remove(0);al_data2.display();cout << "\n删除al_data2中下标为0的元素:" << endl;al_data2.remove(0);al_data2.display();cout << endl;return 0;
}

整体测试结果如下图所示:

《编码规范和测试方法——C/C++版》作业 ·004——设计一个顺序表相关推荐

  1. 《编码规范和测试方法——C/C++版》作业 ·003——宏定义作用整理、设计删除数组元素的函数

    文章目录 一.宏定义(#define)的作用 1.普通宏 2.带参宏 [注]:特殊用法 3.其他用法和注意点 二.实际问题(函数设计) 1.原题 2.题解参考 (1).面向过程的设计 (2).面向对象 ...

  2. 《编码规范和测试方法——C/C++版》作业 ·008——编写一个符合依赖倒置原则的简单学生管理系统

    文章目录 问题描述 参考解答 整体架构 UML图 整体代码 MySQL-C-API封装 Model层 Dao层 Service层 Controller层 View层 主程序 测试环境 测试流程 测试效 ...

  3. 《编码规范和测试方法——C/C++版》学习笔记 ·001

    文章目录 一.编码规范的目的 二.相关知识补充 1.32位机下C++中各变量占用的字节数 2.按位操作 三.规范事项 1.把常量放在==左边 2.按位位移操作的右操作数必须小于操作的位数 3.不要对有 ...

  4. 《编码规范和测试方法——C/C++版》作业 ·007——C++引入MySQL给C的API并简单封装

    文章目录 问题描述 参考解答 API引入 API测试 一些问题 封装代码 测试环境 测试代码 测试结果 问题描述 使用MySQL为C提供的API,封装出一个访问MySQL数据库的类.要求至少能实现如下 ...

  5. 《编码规范和测试方法——C/C++版》作业 ·006——设计模式 · 模板方法

    文章目录 一.设计模式-模板方法 1.简单介绍 2.框架演示 3.实际案例 一.设计模式-模板方法 1.简单介绍 简单来说,就是先在父类FFF中定义好一个函数AAA,然后这个函数AAA代表了一个操作M ...

  6. 《编码规范和测试方法——C/C++版》作业 ·005——设计一组员工类

    问题描述 Cola公司的雇员分为以下若干类:ColaEmployee :所有员工总的父类属性:员工的姓名,员工的生日月份方法:getSalary(int month) 根据参数月份来确定工资,如果该月 ...

  7. 《编码规范和测试方法——C/C++版》作业 ·002——函数返回地址、static关键词用法整理

    文章目录 一.函数返回地址的情形 1.函数返回值为指针 二.static关键字用法整理 1.static全局变量 2.static局部变量 3.static函数 4.类的static成员数据 5.类的 ...

  8. 《编码规范和测试方法——C/C++版》学习笔记 ·002

    文章目录 一.相关知识补充 1.switch接受的参数类型 2.内存分区与数据存放 3.变量的作用域与生命期 4.调试开关的使用 二.规范事项 1.杂项 (1).for循环语句中只出现影响循环控制的变 ...

  9. 第五版人民币冠号印制顺序表

    第五版人民币冠号印制顺序表--人民币英文冠字印制顺序表 第一大组(1组,组)                        F组 FA FB FC FD FE FF FG FH FI FJ       ...

最新文章

  1. KS008基于SSM的新闻发布系统
  2. HTTP 调试工具httpdebug 使用示例
  3. 网络时间服务和chrony
  4. QQ注册时间查询非常准确源码程序
  5. Docker-images
  6. Tkinter Frame size
  7. RPM的原理及rpm命令常用参数
  8. 如何查看APP ID
  9. 新手入门:手把手从PHP环境到ThinkPHP6框架下载
  10. 从几个实例来记忆Activity的生命周期
  11. 8g u盘容量变小格式化u盘内存变小--已解决
  12. 生产环境 java.util.concurrent.RejectedExecutionException: event executor terminated 错误分析
  13. 【校内模拟】五彩斑斓(拓扑排序)
  14. matlab里添加白噪声,转Matlab中添加高斯白噪声
  15. android圆环头像,Android实现带圆环的圆形头像
  16. 匿名飞控STM32版代码整理之Ano_Imu.c
  17. 10分钟教你如何自动化操控浏览器——Selenium测试工具
  18. 2022京东双十一全品类销售额变化情况一览:50%增长,50%下滑
  19. g33k 专用:使用 Mutt Email 客户端管理你的 Gmail
  20. matlab中关于fix(x),floor(x),ceil(x)的区别

热门文章

  1. Linux的用户管理
  2. c# 访问hbase_大数据技术之C#通过Thrift连接查询HBase主要方法总结
  3. jquery实现app开发闹钟功能_一款让你真正摆脱懒觉的“闹钟APP软件”
  4. android qq音乐api使用,QQ音乐API
  5. 用yacc编写的算术运算计算器_如何用纯机械实现乘除运算,这是个问题
  6. php 如何打乱数组顺序,【PHP打乱数组顺序的方法有哪些,这样的程序你真的会写吗】- 环球网校...
  7. 吝啬的国度(dfs)
  8. algorithm头文件下的fill()
  9. Python注释的写作笔记
  10. Jupyter Lab——无法显示matplotlib绘制的图像