STL-vector模拟实现
#pragma once
#include<assert.h>
#include<iostream>
using std::cout;
using std::endl;
using std::cin; namespace test
{ //#include<algorithm>
//模板参数省略:1.作为时 2.作为类型名
template <class T> //数组名:类型名:xx数组
class vector
{
public:
//成员类型 //也可以用内部类,但C++都是typedef居多,不喜欢内部类
typedef T* iterator;
typedef const T* const_iterator;
private:
//构造函数太多,初始化列表重复太多麻烦,直接给缺省参数方便//C++11
iterator _start = nullptr; //数组头
iterator _finish = nullptr;//数组有效数据尾的下一个(类似\0位置)
iterator _end_of_storage = nullptr;//数组容量尾的下一个位置,有效空间的下一个位置 public:
//无参构造
vector()
{}
//有参构造:开辟n个空间,1.数量 2开辟对象空间
vector(size_t n, const T& val = T()) //缺省值为显式匿名构造,基本类型也支持
{
//_start = new T[n];
//_finish = _start + n;
//_end_of_storage = _start + n;
//for (size_t i = 0; i < n; ++i)
//{
// _start[i] = val;
//}
reserve(n);
for (size_t i = 0; i < n; ++i)
{
push_back(val);
}
}
//有参构造整型重载
vector(int n, const T& val = T()) {
reserve(n);
for (size_t i = 0; i < n; ++i)
{
push_back(val);
}
}
//迭代器构造
template <class InputIterator>
vector(InputIterator first, InputIterator last) {
//size_t sz = last - first;
//_start = _finish = new T[sz];
//while (first != last)
//{
// *_finish = *first;
// ++first;
// ++_finish;
//}
//_end_of_storage = _start + sz;
while (first != last)
{
push_back(*first);
++first;
}
} //C++11 initializer_list 构造
vector(std::initializer_list<T> il) //常量不能引用
{
//两种写法
//typename std::initializer_list<T>::iterator it = il.begin();
//while (it != il.end())
//{
// push_back(*it);
// ++it;
//} for (auto e : il)
{
push_back(e);
}
} ~vector()
{
delete[] _start;
_start = _finish = _end_of_storage = nullptr;
} //拷贝构造
vector(const vector<T>& v)
{
//_start = new T[v.capacity()];
//for (size_t i = 0; i < v.size(); ++i)
//{
// _start[i] = v._start[i];//这里可能用到重载=,从而实现深拷贝
//}
//_finish = _start + v.size();
//_end_of_storage = _start + v.capacity();
vector<T> tmp(v.begin(), v.end());
swap(tmp); } void swap(vector<T>& v)
{
//不能使用赋值,死循环
//_start = v._start;
//_finish = v._finish;
//_end_of_storage = v._end_of_storage; //由于是拷贝的空间,且不能使用赋值,故交换掉,原先的会释放掉,
//旧空间已经交换给v了,v会在出了作用域后回收,所以不用手动释放
std::swap(_start, v._start);
std::swap(_finish, v._finish);
std::swap(_end_of_storage, v._end_of_storage);
} vector<T>& operator=(vector<T> v) //深拷贝
//赋值运算符重载:操作数是vector<vector<>>,在非初始化时走这里,初始化时时拷贝构造
//传值传参,v是拷贝,所以是再次调了拷贝构造,新空间了,所以相当于深拷贝
{
swap(v);
return *this;
} iterator begin()
{
return _start;
} iterator end()
{
return _finish;
}
const_iterator begin() const
{
return _start;
}
const_iterator end() const
{
return _finish;
} //Capacity
size_t capacity() const
{
return _end_of_storage - _start;
}
size_t size() const
{
return _finish - _start;
}
bool empty() const
{
return _start == _finish;
}
T& operator[](size_t pos) //_start的类型是对象,所以返回迭代器
{
assert(pos < size());
return _start[pos];
}
const T& operator[](size_t pos)const
{
assert(pos < size());
return _start[pos];
} void resize(size_t n, const T& val = T())
{
if (n > capacity())
{
reserve(n);
} if (n > size())
{
while (_finish < _start + n)
{
*_finish = val;
++_finish;
}
}
else
{
_finish = _start + n;
}
} void reserve(size_t n) //扩容
{
if (n > capacity())
{
size_t sz = size();
T* tmp = new T[n];
//memcpy()//可能会有浅拷贝
for (size_t i = 0; i < sz; ++i)
{
tmp[i] = _start[i];
}
delete[] _start;
_start = tmp;
_finish = tmp + sz; //必须放在后面,因为size与_finish有关
_end_of_storage = tmp + n;
}
} void push_back(const T& x)//尾插
{
if (_finish == _end_of_storage)
{
size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
reserve(newCapacity);
}
*_finish = x;
++_finish;
} void pop_back() //尾删
{
//if (empty())
//{
// return;
//}
assert(!empty());
--_finish;
} iterator insert(iterator pos, const T& val)//插入//返回原来插入的位置
{
assert(pos >= _start);
assert(pos <= _finish);
if (_finish == _end_of_storage)//reserve后迭代器失效
{
size_t len = _end_of_storage - _start;
size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
reserve(newCapacity); pos = _start + len; // 扩容会导致pos迭代器失效,需要更新处理一下
}
iterator end = _finish; //减少用end
while (end >= pos)
{
*(end + 1) = *end;
--end;
}
*pos = val;
++_finish;
return pos; //防止迭代器可能因为扩容而失效,因此将迭代器作为返回值 }
iterator erase(iterator pos)//删除 //返回删除的下一个位置
{
assert(pos >= _start);
assert(pos < _finish);
iterator begin = pos + 1; //增加用begin
while (begin != _finish)
{
*(begin - 1) = *begin;
++begin;
} --_finish;
return pos;
}
}; //测试用例
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> vv;
vv.resize(numRows, vector<int>()); for (size_t i = 0; i < vv.size(); ++i)
{
vv[i].resize(i + 1, 0);
vv[i][0] = vv[i][vv[i].size() - 1] = 1; for (size_t j = 0; j < vv[i].size(); ++j)
{
if (vv[i][j] == 0)
{
vv[i][j] = vv[i - 1][j - 1] + vv[i - 1][j];
}
}
}
return vv;
}
}; void test_vector4()
{
using namespace std;
vector<vector<int>> vv = Solution().generate(3);
for (size_t i = 0; i < vv.size(); ++i)
{
for (size_t j = 0; j < vv[i].size(); ++j)
{
cout << vv[i][j] << " ";
}
cout << endl;
}
cout << endl; vector<vector<int>> v3 = vv;//初始化=是拷贝构造 ,深拷贝过程中=是重载
for (size_t i = 0; i < v3.size(); ++i)
{
for (size_t j = 0; j < v3[i].size(); ++j)
{
cout << v3[i][j] << " ";
}
cout << endl;
} vector<int> v1;
v1.resize(3, 1);
vector<int> v2 = v1; //初始化=是拷贝构造
for (auto e : v2)
{
cout << e << " ";
}
} void test_vector5()
{
vector<int> v = { 1,2,3,4,5 }; //initializer_list 初始化 } }
STL-vector模拟实现的更多相关文章
- <泛> STL - vector 模拟实现
今天为大家带来一个模拟STL-vector的模板实现代码. 首先看一下测试结果,之后再为大家呈现设计 测试效果 测试代码 #include<iostream> #include<ve ...
- 利用C++ STL的vector模拟邻接表的代码
关于vector的介绍请看 https://www.cnblogs.com/zsq1993/p/5929806.html https://zh.cppreference.com/w/cpp/conta ...
- uva 101 POJ 1208 The Blocks Problem 木块问题 vector模拟
挺水的模拟题,刚开始题目看错了,poj竟然过了...无奈.uva果断wa了 搞清题目意思后改了一下,过了uva. 题目要求模拟木块移动: 有n(0<n<25)快block,有5种操作: m ...
- C++ STL vector容器学习
STL(Standard Template Library)标准模板库是C++最重要的组成部分,它提供了一组表示容器.迭代器.函数对象和算法的模板.其中容器是存储类型相同的数据的结构(如vector, ...
- STL vector
STL vector vector是线性容器,它的元素严格的按照线性序列排序,和动态数组很相似,和数组一样,它的元素存储在一块连续的存储空间中,这也意味着我们不仅可以使用迭代器(iterator)访问 ...
- STL vector用法介绍
STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和f ...
- STL vector+sort排序和multiset/multimap排序比较
由 www.169it.com 搜集整理 在C++的STL库中,要实现排序可以通过将所有元素保存到vector中,然后通过sort算法来排序,也可以通过multimap实现在插入元素的时候进行排序.在 ...
- STL vector 用法介绍
介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...
- STL vector使用方法介绍
介绍 这篇文章的目的是为了介绍std::vector,怎样恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...
- stl——vector详解
stl——vector详解 stl——vector是应用最广泛的一种容器,类似于array,都将数据存储于连续空间中,支持随机访问.相对于array,vector对空间应用十分方便.高效,迭代器使ve ...
随机推荐
- ccs3动画-div向上移动的动画
<head> <meta charset="UTF-8"> <meta name="viewport" content=" ...
- hover时行级元素变成了块级元素,导致位置错乱
在hover时,i元素变成了块级元素: 导致这两个元素各自占了一行: 最终导致样式错乱: <div class="demo"> <!-- 添加图标 和 编辑图标 ...
- ClickHouse(22)ClickHouse集成HDFS表引擎详细解析
HDFS 这个引擎提供了与Apache Hadoop生态系统的集成,允许通过ClickHouse管理HDFS上的数据.这个引擎提供了Hadoop的特定功能. 用法 ENGINE = HDFS(URI, ...
- windowsbat删除命令
widnwosbat命令 DEL /F /A /Q \?%1 用于删除指定路径下的文件,参数含义如下: /F: Force delete,即强制删除: /A: 用于指定文件属性,A代表存档,D代表目录 ...
- @RequestBody中使用@DateTimeFormat报错:JSON parse error: Expected array or string.; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException
原因分析 根据异常提示:不匹配输入异常,指输入的参数错误,说是只支持String类型和Array数组类型的. @PostMapping("/test") public Dto ge ...
- Linux系统的一些实用操作 [补档-2023-07-30]
Linux的实用操作 4-1.常用快捷键 强制停止:当某些程序运行时,或者命令输入错误时,可以通过 ctrl + c 来强制结束当前的操作. 退出或登出:当我们要退出某些用户时,或者要退出某些特殊的页 ...
- 《熬夜整理》保姆级系列教程-玩转Wireshark抓包神器教程(1)-初识Wireshark
1.简介 前边已经介绍过两款抓包工具,应该是够用了,也能够处理在日常工作中遇到的问题了,但是还是有人留言让宏哥要讲解讲解Wireshark这一款抓包工具,说实话宏哥之前也没有用过这款工具,只能边研究边 ...
- 【STL源码剖析】string类模拟实现 了解底层-走进底层-掌握底层【超详细的注释和解释】
文章目录 博主对大家的话 前言 实现过程一些要注意的点 STL中string类模拟实现 尾声 博主对大家的话 从今天开始,STL源码剖析的专栏就正式上线了!其实在很多人学习C++过程中,都是只学习一些 ...
- Vulkan学习苦旅04:创建设备(逻辑设备VkDevice)
设备是对物理设备的一种抽象,使我们更加方便地使用它.更准确地说,应该称其为"逻辑设备",但由于逻辑设备在Vulkan中极为常用,后面几乎所有的API都需要它作为第一个参数,因此在V ...
- 【DC渗透系列DC-4】
主机发现 arp-scan -l ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:6b: ...