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 ...
随机推荐
- 【JS 逆向百例】拉勾网爬虫,traceparent、__lg_stoken__、X-S-HEADER 等参数分析
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...
- C#对象属性浅拷贝和深拷贝
对象属性和字段拷贝的几种方式 微软提供了浅拷贝 对于值类型,修改拷贝的值不会影响源对象 对于引用类型,修改拷贝后的值会影响源对象,但string特殊,它会拷贝一个副本,互相不会影响 自己实现深拷贝,我 ...
- 部署MooseFS分布式文件系统
MooseFS是一个分布式文件系统,其本身具有高可用性,高拓展性,开放源代码,高容错,等在数据的读写性能方面,通过dd测试,MooseFS也就是写入的速度稍微好于NFS,读上没有差别. MooseFS ...
- MyBatis 源码系列:MyBatis 解析配置文件、二级缓存、SQL
解析全局配置文件 启动流程分析 String resource = "mybatis-config.xml"; //将XML配置文件构建为Configuration配置类 read ...
- 为Win12做准备?微软Win11 23H2将集成AI助手:GPT4免费用
微软日前确认今年4季度推出Win11 23H2,这是Win11第二个年度更新. Win11 23H2具体有哪些功能升级,现在还不好说,但它会集成微软的Copilot,它很容易让人想到多年前的" ...
- HBase-表的压缩
一.如何选择压缩算法以及Data_Block_Encoding?(1)如果Key很长,或者有很多Column,那么推荐使用FAST_DIFF.(2)如果数据是冷数据,不经常被访问,那么使用GZIP压缩 ...
- Python-pymysql操作MySQL数据库
一.安装pymysql py -m pip install pymysql; 二.pymysql数据库操作 1.简单示例 #coding=utf-8 import pymysql ## 打开数据库连接 ...
- linux 搭建http文件服务器
1.安装httpd服务 yum -y install httpd 2.修改需要访问的文件路径 vi /etc/httpd/conf/httpd.conf ##默认是/var/www/html目录下的文 ...
- java 注解结合 spring aop 实现自动输出日志
auto-log auto-log 是一款为 java 设计的自动日志监控框架. 创作目的 经常会写一些工具,有时候手动加一些日志很麻烦,引入 spring 又过于大材小用. 所以希望从从简到繁实现一 ...
- 使用JS访问本地数据库
1 前言 有时候,数据业务比较大,比如查询百万级的数据,如果使用JSP查询数据库,JSP的返回结果一般放在域名后面返回给客户端,而返回结果的长度是有限制的,数据过长可能会丢失部分数据:另一方面数据量大 ...