Myclass.h

#pragma once
#include<iostream>
#include<Windows.h>
#define SUCCESS 1 // 成功
#define ERROR -1 // 失败
#define MALLOC_ERROR -2 // 申请内存失败
#define INDEX_ERROR -3 // 错误的索引号 template <class T_ELE>
class Vector
{
public:
Vector();
Vector(DWORD dwSize);
~Vector();
public:
DWORD at(DWORD dwIndex, OUT T_ELE* pEle); //根据给定的索引得到元素
DWORD push_back(T_ELE Element); //将元素存储到容器最后一个位置
BOOL pop_back(); //删除最后一个元素
DWORD insert(DWORD dwIndex, T_ELE Element); //向指定位置新增一个元素
DWORD capacity(); //返回在不增容的情况下,还能存储多少元素
VOID clear(); //清空所有元素
BOOL empty(); //判断Vector是否为空 返回true时为空
DWORD erase(DWORD dwIndex); //删除指定元素
DWORD size(); //返回Vector元素数量的大小
private:
BOOL expand();
private:
DWORD m_dwIndex; //下一个可用索引
DWORD m_dwIncrement; //每次增容的大小
DWORD m_dwLen; //当前容器的长度
DWORD m_dwInitSize; //默认初始化大小
T_ELE* m_pVector; //容器指针
}; //构造函数(不带参数)
template <class T_ELE>
Vector<T_ELE>::Vector()
:m_dwInitSize(10), m_dwIncrement(5)
{
//1.创建长度为m_dwInitSize个T_ELE对象
m_pVector = new T_ELE[m_dwInitSize]; //2.将新创建的空间初始化
memset(m_pVector, 0, m_dwInitSize * sizeof(T_ELE)); //3.设置其他值
m_dwLen = m_dwInitSize;
m_dwIndex = 0; } //构造函数(带参数)
template <class T_ELE>
Vector<T_ELE>::Vector(DWORD dwSize)
:m_dwIncrement(5)
{
//1.创建长度为dwSize个T_ELE对象
m_pVector = new T_ELE[dwSize]; //2.将新创建的空间初始化
memset(m_pVector, 0, dwSize * sizeof(T_ELE)); //3.设置其他值
m_dwLen = dwSize;
m_dwIndex = 0;
} //析构函数
template <class T_ELE>
Vector<T_ELE>::~Vector()
{ //释放空间 delete[]
delete[] m_pVector;
m_pVector = NULL;
} template <class T_ELE>
BOOL Vector<T_ELE>::expand()
{
DWORD dwTempLen = 0;
T_ELE* pTemp = NULL;
// 1. 计算增加后的长度
dwTempLen = m_dwLen + m_dwIncrement; // 2. 申请空间
pTemp = new T_ELE[dwTempLen]; // 3. 将数据复制到新的空间
memcpy(pTemp,m_pVector,sizeof(T_ELE)*m_dwLen); // 4. 释放原来空间
delete[] m_pVector;
m_pVector = pTemp;
pTemp = NULL; // 5. 为各种属性赋值
m_dwLen = dwTempLen; return TRUE; } //将元素存储到容器最后一个位置
template <class T_ELE>
DWORD Vector<T_ELE>::push_back(T_ELE Element)
{
//1.判断是否需要增容,如果需要就调用增容的函数
if (m_dwIndex >= m_dwLen)
{
expand();
}
//2.将新的元素复制到容器的最后一个位置
memcpy(&m_pVector[m_dwIndex],&Element,sizeof(T_ELE));
//3.修改属性值
m_dwIndex++; return SUCCESS;
} //删除最后一个元素
template<class T_ELE>
BOOL Vector<T_ELE>::pop_back() {
/*if (m_dwLen > 0) {
memset(m_pVector + m_dwLen, 0, sizeof(T_ele));
m_dwLen--;
}
*/
//下面这个是删除当前元素中最后一个元素的方法,上面注释那个是删除整个容器最后一个容器
if (m_dwIndex > 0) {
memset(m_pVector + (m_dwIndex - 1), 0, sizeof(T_ELE));
m_dwIndex--;
return TRUE;
}
} //向指定位置新增一个元素
template <class T_ELE>
DWORD Vector<T_ELE>::insert(DWORD dwIndex, T_ELE Element)
{
//1.判断索引是否在合理区间
if(dwIndex<0|| dwIndex>m_dwIndex)
{
return INDEX_ERROR;
} //2.判断是否需要增容,如果需要就调用增容的函数
if(dwIndex>=m_dwLen)
{
expand();
} //3.将dwIndex只后的元素后移
for(int i = m_dwIndex;i> dwIndex;i--)
{
memcpy(&m_pVector[i], &m_dwIndex[i - 1], sizeof(T_ELE));
} //4.将Element元素复制到dwIndex位置
memcpy(&m_dwIndex[dwIndex],&Element,sizeof(T_ELE)); //5.修改属性值
m_dwIndex++;
} //根据给定的索引得到元素
template <class T_ELE>
DWORD Vector<T_ELE>::at(DWORD dwIndex, T_ELE* pEle)
{
//判断索引是否在合理区间
if (dwIndex<0 || dwIndex>=m_dwIndex)
{
return INDEX_ERROR;
} //将dwIndex的值复制到pEle指定的内存
memcpy(&pEle, &m_pVector[dwIndex], sizeof(T_ELE));
} //删除指定元素
template <class T_ELE>
DWORD Vector<T_ELE>::erase(DWORD dwIndex)
{
//1.判断索引是否在合理区间
if (dwIndex <0 || dwIndex >= m_dwIndex || dwIndex > m_dwLen)
{
return INDEX_ERROR;
} //2.将dwindex之后的元素前移
for (int i = dwIndex; i < m_dwIndex - 1; i++)
{
memcpy(&m_pVector[i], &m_pVector[i + 1], sizeof(T_ELE));
} //3.修改属性值
m_dwIndex--;
} //判断Vector是否为空 返回true时为空
template<class T_ELE>
BOOL Vector<T_ELE>::empty() {
if (m_pVector == NULL or m_dwIndex = 0) {
return true;
}
return false;
} template<class T_ELE>
DWORD Vector<T_ELE>::size() {
return m_dwLen;
} //查询剩余容量
template<class T_ELE>
DWORD Vector<T_ELE>::capacity() {
if (m_pVector)
{
return m_dwLen - m_dwIndex;
}
return ERROR;
} template<class T_ELE>
void Vector<T_ELE>::clear() {
memset(m_pVector, 0, sizeof(T_ELE) * m_dwLen);
m_dwIndex = 0;
}

Vector.cpp

#include"MyClass.h"
#include"malloc.h" void TestVector()
{
Vector<int>* pVector = new Vector<int>(5); pVector->push_back(1);
pVector->push_back(2);
pVector->push_back(3);
pVector->push_back(4);
pVector->push_back(5);
//pVector->push_back(6); pVector->erase(3); } int main(int argc, char* argv[])
{
TestVector(); return 0;
}

补充一下用vector来定义二维数组

初始化一个二维vector数组并指定大小的方法有:

1. vector<vector<int>> vec(行数, vector<int>(列数));
// 如 vector<vector<int>> vec(3,vector<int>(4)) 定义的就是3行4列(有没有想到汤家凤hhh)的二维数组 2. vector<vector<int>> vec(行数, vector<int>(列数, 初始值));
//如 vector<vector<int>> vec(3,vector<int>(4,1)) 定义的就是3行4列(有没有想到汤家凤hhh)的二维数组,并且二维数组里的数全部初始化为1 3. vector<vector<int>> vec; vec.resize(行数); vec[i].resize(列数); vec[i] = {值};
//这就说明可以定义不同行的列数不相同,可以指定某行的列数

手撕vector的更多相关文章

  1. NN入门,手把手教你用Numpy手撕NN(一)

    前言 这是一篇包含极少数学推导的NN入门文章 大概从今年4月份起就想着学一学NN,但是无奈平时时间不多,而且空闲时间都拿去做比赛或是看动漫去了,所以一拖再拖,直到这8月份才正式开始NN的学习. 这篇文 ...

  2. NN入门,手把手教你用Numpy手撕NN(2)

    这是一篇包含较少数学推导的NN入门文章 上篇文章中简单介绍了如何手撕一个NN,但其中仍有可以改进的地方,将在这篇文章中进行完善. 误差反向传播 之前的NN计算梯度是利用数值微分法,虽容易实现,但是计算 ...

  3. 手撕代码:统计1到n二进制数中1出现的总次数

    题目描述: 互娱手撕代码题. 统计从1到n这n个数的二进制表示中1出现的次数. 思路分析: 思路一:直接的做法是从1遍历到n,对于每个数和1做与操作,之后,对于这个数不断做右移操作,不断和1做与操作, ...

  4. 编译原理--05 用C++手撕PL/0

    前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...

  5. 手撕Ford-Fulkerson algorithm 学一半的笔记

    目录 定义大概就这些 伪代码 自己做slide里的quiz 搬运别人的代码 我明白了, 余量网络 名如其名 比如你f/c=3/5 那么正边2,reverse edge3,加起来是5 在这个你建的新图上 ...

  6. Netty实现高性能IOT服务器(Groza)之手撕MQTT协议篇上

    前言 诞生及优势 MQTT由Andy Stanford-Clark(IBM)和Arlen Nipper(Eurotech,现为Cirrus Link)于1999年开发,用于监测穿越沙漠的石油管道.目标 ...

  7. 手撕RPC框架

    手撕RPC 使用Netty+Zookeeper+Spring实现简易的RPC框架.阅读本文需要有一些Netty使用基础. 服务信息在网络传输,需要讲服务类进行序列化,服务端使用Spring作为容器.服 ...

  8. 手撕公司SSO登陆原理

    Single Sign-on SSO是老生常谈的话题了,但部分同学对SSO可能掌握的也是云里雾里,一知半解.本次手撕公司的SSO登陆原理,试图以一种简单,流畅的形式为你提供 有用的SSO登陆原理. 按 ...

  9. NN入门,手把手教你用Numpy手撕NN(三)

    NN入门,手把手教你用Numpy手撕NN(3) 这是一篇包含极少数学的CNN入门文章 上篇文章中简单介绍了NN的反向传播,并利用反向传播实现了一个简单的NN,在这篇文章中将介绍一下CNN. CNN C ...

  10. 手撕ES6--Promise

    手撕ES6--Promise:https://www.jianshu.com/p/0925eae38d2c 手写一个Promise,附源码分析:https://blog.csdn.net/weixin ...

随机推荐

  1. Docker基本操作(镜像操作?容器操作?)(四)

    Docker 的基本原理我们已经了解了,也已经安装上了,接下来我们就一起来学习下 Docker 的常用操作,实际上主要就是 Docker CLI 的一些常用命令使用. 一.镜像操作 之前我们提到过 D ...

  2. 支持Docker的底层技术(Namespaces?CGroups?UnionFS?Docker 架构?)(二)

    上一篇介绍了Docker基本概念,这一篇介绍下支持Docker的底层技术 Docker 本质就是宿主机的一个特殊进程,Docker 是通过 namespace 实现资源隔离,通过cgroup 实现资源 ...

  3. MSF使用方法

    https://blog.csdn.net/weixin_45588247/article/details/119614618https://github.com/ttonys/Scrapy-CVE- ...

  4. 使用SourceTree管理仓库代码

    1.首先我们需要下载sourcetree,你可以去官网下载自己需要的版本. 2.安装完毕之后,我们需要获取ssh密钥与github关联上才能使用 按下面的操作开始执行.确定之后,会出现一个字符界面,输 ...

  5. 墨天轮访谈 | SelectDB 衣国垒:Apache Doris(incubating)1.0版本特性解析与未来规划

    分享嘉宾:衣国垒 Apache Doris Committer.SelectDB 联合创始人&CTO 整理:墨天轮社区 导读 大家好,我是来自Apache Doris社区的衣国垒,也是Sele ...

  6. excel导出功能的实现流程说⼀下?

    导出的话,我们因为到处的数据量不⼤,所以直接采取的时候前端主导的⽅案,参考的现成⽅案实现的 导出 ⼤概得流程就是 1. 调⽤后端接⼝得到要导出的数据 2. 把数据简单处理⼀下转化成导出插件需要的格式 ...

  7. Vue3 的emit3 属性和 props 属性?

    使用场景:使用父子组件通信的时候 : 作用: 用来声明组件有哪些自定义事件,不在emtis里面都会当成原生事件,绑定给组件的根标 签. 好处: 不在像 vue2 使用  .native 修饰符 在 v ...

  8. 云原生爱好者周刊:Dapr 成为 CNCF 孵化项目

    云原生一周动态要闻: Dapr 加入 CNCF 孵化器 Knative 1.0 发布 Canonical 开始提供针对 Intel CPU 优化的 Ubuntu 图像 Longhorn 为 CNCF ...

  9. idea项目提交到码云

    第一步:创建一个项目 第二步:在码云上新建一个项目.[注意把使用Readme复选框取消掉] 第三步:复制gitee地址 第四步:创建本地git仓库 第五步:选择自己需要上传到码云的项目名 第六步:提交 ...

  10. 轻量级网络-MobileNetv1 论文解读

    1.相关工作 标准卷积 分组卷积 从 Inception module 到 depthwise separable convolutions 2.MobileNets 结构 2.1,深度可分离卷积 D ...