《编码规范和测试方法——C/C++版》作业 ·004——设计一个顺序表
问题描述
实现一个能够实现自动扩容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——设计一个顺序表相关推荐
- 《编码规范和测试方法——C/C++版》作业 ·003——宏定义作用整理、设计删除数组元素的函数
文章目录 一.宏定义(#define)的作用 1.普通宏 2.带参宏 [注]:特殊用法 3.其他用法和注意点 二.实际问题(函数设计) 1.原题 2.题解参考 (1).面向过程的设计 (2).面向对象 ...
- 《编码规范和测试方法——C/C++版》作业 ·008——编写一个符合依赖倒置原则的简单学生管理系统
文章目录 问题描述 参考解答 整体架构 UML图 整体代码 MySQL-C-API封装 Model层 Dao层 Service层 Controller层 View层 主程序 测试环境 测试流程 测试效 ...
- 《编码规范和测试方法——C/C++版》学习笔记 ·001
文章目录 一.编码规范的目的 二.相关知识补充 1.32位机下C++中各变量占用的字节数 2.按位操作 三.规范事项 1.把常量放在==左边 2.按位位移操作的右操作数必须小于操作的位数 3.不要对有 ...
- 《编码规范和测试方法——C/C++版》作业 ·007——C++引入MySQL给C的API并简单封装
文章目录 问题描述 参考解答 API引入 API测试 一些问题 封装代码 测试环境 测试代码 测试结果 问题描述 使用MySQL为C提供的API,封装出一个访问MySQL数据库的类.要求至少能实现如下 ...
- 《编码规范和测试方法——C/C++版》作业 ·006——设计模式 · 模板方法
文章目录 一.设计模式-模板方法 1.简单介绍 2.框架演示 3.实际案例 一.设计模式-模板方法 1.简单介绍 简单来说,就是先在父类FFF中定义好一个函数AAA,然后这个函数AAA代表了一个操作M ...
- 《编码规范和测试方法——C/C++版》作业 ·005——设计一组员工类
问题描述 Cola公司的雇员分为以下若干类:ColaEmployee :所有员工总的父类属性:员工的姓名,员工的生日月份方法:getSalary(int month) 根据参数月份来确定工资,如果该月 ...
- 《编码规范和测试方法——C/C++版》作业 ·002——函数返回地址、static关键词用法整理
文章目录 一.函数返回地址的情形 1.函数返回值为指针 二.static关键字用法整理 1.static全局变量 2.static局部变量 3.static函数 4.类的static成员数据 5.类的 ...
- 《编码规范和测试方法——C/C++版》学习笔记 ·002
文章目录 一.相关知识补充 1.switch接受的参数类型 2.内存分区与数据存放 3.变量的作用域与生命期 4.调试开关的使用 二.规范事项 1.杂项 (1).for循环语句中只出现影响循环控制的变 ...
- 第五版人民币冠号印制顺序表
第五版人民币冠号印制顺序表--人民币英文冠字印制顺序表 第一大组(1组,组) F组 FA FB FC FD FE FF FG FH FI FJ ...
最新文章
- KS008基于SSM的新闻发布系统
- HTTP 调试工具httpdebug 使用示例
- 网络时间服务和chrony
- QQ注册时间查询非常准确源码程序
- Docker-images
- Tkinter Frame size
- RPM的原理及rpm命令常用参数
- 如何查看APP ID
- 新手入门:手把手从PHP环境到ThinkPHP6框架下载
- 从几个实例来记忆Activity的生命周期
- 8g u盘容量变小格式化u盘内存变小--已解决
- 生产环境 java.util.concurrent.RejectedExecutionException: event executor terminated 错误分析
- 【校内模拟】五彩斑斓(拓扑排序)
- matlab里添加白噪声,转Matlab中添加高斯白噪声
- android圆环头像,Android实现带圆环的圆形头像
- 匿名飞控STM32版代码整理之Ano_Imu.c
- 10分钟教你如何自动化操控浏览器——Selenium测试工具
- 2022京东双十一全品类销售额变化情况一览:50%增长,50%下滑
- g33k 专用:使用 Mutt Email 客户端管理你的 Gmail
- matlab中关于fix(x),floor(x),ceil(x)的区别
热门文章
- Linux的用户管理
- c# 访问hbase_大数据技术之C#通过Thrift连接查询HBase主要方法总结
- jquery实现app开发闹钟功能_一款让你真正摆脱懒觉的“闹钟APP软件”
- android qq音乐api使用,QQ音乐API
- 用yacc编写的算术运算计算器_如何用纯机械实现乘除运算,这是个问题
- php 如何打乱数组顺序,【PHP打乱数组顺序的方法有哪些,这样的程序你真的会写吗】- 环球网校...
- 吝啬的国度(dfs)
- algorithm头文件下的fill()
- Python注释的写作笔记
- Jupyter Lab——无法显示matplotlib绘制的图像