当前位置: 首页 > news >正文

reverse_iterator实现

对于实现reverse_iterator,我们可以学栈和队列的实现过程,利用适配器,实现如下;

#pragma oncetemplate<class Iterator,class Ref,class Ptr>
class reverse_Iterator
{
public://构造函数:reverse_Iterator(Iterator it):_it(it){}typedef reverse_Iterator<Iterator, Ref, Ptr> Self;//操作:bool operator!=(const Self& cur){return !(_it == cur._it);}bool operator==(const Self& cur){return _it == cur._it;}Self& operator++(){_it--;return *this;}Self operator++(int){Self tmp(*this);_it--;return tmp;}Self& operator--(){_it++;return *this;}Self operator--(int){Self tmp(*this);_it++;return tmp;}Ref operator*(){//解引用是找前一个:Iterator tmp = _it;return *(--tmp);}Ptr operator&(){//取地址也是找前一个:return &(operator*());}
private:Iterator _it;
};

此时我们将实现的reverse_iterator添加到vector和list上如下:

(注意:vector、list其余部分之前已经实现过了)

vector.h

#pragma once
#include <assert.h>
#include <iostream>
#include <string.h>
#include "reverse_iterator.h"
namespace cx
{//模板类template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;typedef reverse_Iterator<iterator, T&, T*> reverse_iterator;typedef reverse_Iterator<const_iterator, const T&, const T*> const_reverse_iterator;//构造函数:vector(){}//传统写法/*vector(const vector<T>& v){_start = new T[v.capacity()];memcpy(_start, v._start, v.size() * sizeof(T));_finish = _start + v.size();_endofstorage = _start + v.capacity();}*///现代写法:vector(const vector<T>& v){reserve(v.capacity());for (const auto e : v){*_finish = e;_finish++;}}vector(size_t n, const T& val = T()){resize(n,val);}/*template <class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);first++;}}*///析构函数~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}vector<T>& operator=(vector<T> 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;}reverse_iterator rend(){return _start;}reverse_iterator rbegin(){return _finish;}const_reverse_iterator crend()const{return _start;}const_reverse_iterator crbegin()const{return _finish;}//计算大小size_t size()const {return end() - begin();}size_t capacity()const {return _endofstorage - _start;}//操作:bool empty() const{return _finish == _start;}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}void reserve(size_t n){if (n > capacity()){size_t old = size();T* tmp = new T[n];if (_start){memcpy(tmp, _start, sizeof(T) * old);delete[] _start;}_start = tmp;_finish = _start + old;_endofstorage = _start + n;}}void push_back(const T x){//检查是否扩容if (_finish == _endofstorage){size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();reserve(newcapacity);}*_finish = x;_finish++;}void pop_back(){assert(size() > 0);_finish--;}T& operator[](size_t pos){assert(pos < size());return _start[pos];}T& operator[] (size_t pos) const{assert(pos < size());return _start[pos];}iterator insert(iterator pos, const T& val){assert(pos <= _finish && pos >= _start);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : 2 * capacity());pos = _start + len;}//memmove(pos + 1, pos, sizeof(T) * (_finish - pos));iterator end = _finish - 1;while (end >= pos){*(end + 1) = *(end);end--;}*pos = val;_finish++;return pos;}/*void insert(iterator pos, const T& x){//检查assert(pos >= _start);assert(pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : 2 * capacity());//注意:pos位置也要改变pos = _start + len;}memmove(pos + 1, pos, sizeof(T) * (_finish - pos));*pos = x;_finish++;}*/iterator erase(iterator pos){assert(pos < _finish && pos >= _start);iterator it = pos + 1;while (it < _finish){*(it - 1) = *it;it++;}_finish--;return pos;}iterator erase(iterator first, iterator last){}void resize(size_t n, T val = T()){if (n > size()){reserve(n);while (_finish < _start + n){*_finish = val;_finish++;}}else{_finish = _start + n;}}T& front(){return *_start;}const T& front() const{*_start;}T& back(){return *_finish;}const T& back() const{return *_finish;}T& at(size_t pos){assert(pos < size());return _start[pos];}const T& at(size_t pos) const{assert(pos < size());return _start[pos];}void assign(size_t n, const T& val){assert(_start == _finish);reserve(n);while (_finish != _endofstorage){*_finish = val;_finish++;}}void clear(){resize(0);}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;};
}

list.h:

#pragma once
#include <assert.h>
#include "reverse_iterator.h"
namespace cx
{template <class T>struct ListNode{//构造函数ListNode(const T& x=T()):_next(nullptr),_prev(nullptr),_val(x){}//成员变量:ListNode<T>* _next;ListNode<T>* _prev;T _val;};template <class T,class Ref,class Ptr>//template <class T, class Ref>struct _list_iterator{typedef ListNode<T> Node;typedef _list_iterator<T,Ref, Ptr> self;//typedef _list_iterator<T, Ref> self;//构造函数://_list_iterator()/*iterator(Node* x):_node(x){}*/_list_iterator(Node* x):_node(x){}//不用写析构:原因在于我们的目标不是在这里析构//常见操作:		self& operator++()//前置++{_node = _node->_next;return (*this);}self operator++(int)//后置++{self tmp(*this);_node = _node->_next;return tmp;}self& operator--()//前置--{_node = _node->_prev;return *this;}self operator--(int)//后置--{self tmp(*this);_node = _node->_prev;return tmp;}Ref operator*(){return _node->_val;}bool operator!=(const self& s){return !(_node == s._node);}bool operator==(const self& s){return !(*this != s);}Ptr operator->(){return &_node->_val;}//类成员函数:Node* _node;};//template <class T>//struct _list_const_iterator//{//	typedef ListNode<T> Node;//	typedef _list_const_iterator<T> const_iterator;//	//构造函数://	//_list_iterator()//	/*iterator(Node* x)//		:_node(x)//	{}*///	_list_const_iterator(Node* x)//		:_node(x)//	{}//	//不用写析构:原因在于我们的目标不是在这里析构//	//常见操作:		//	const_iterator& operator++()//前置++//	{//		_node = _node->_next;//		return (*this);//	}//	const_iterator operator++(int)//后置++//	{//		const_iterator tmp(*this);//		_node = _node->_next;//		return tmp;//	}//	const_iterator& operator--()//前置--//	{//		_node = _node->_prev;//		return *this;//	}//	const_iterator& operator--(int)//后置--//	{//		const_iterator tmp(*this);//		_node = _node->_prev;//		return tmp;//	}//	const T& operator*()//	{//		return _node->_val;//	}//	bool operator!=(const const_iterator& s)//	{//		return !(_node == s._node);//	}//	bool operator==(const const_iterator& s)//	{//		return !(*this != s);//	}//	//类成员函数://	Node* _node;//};template <class T>class list{public:typedef ListNode<T> Node;//typedef _list_iterator<T,T&> iterator;typedef _list_iterator<T, T&, T*> iterator;//typedef _list_iterator<T, const T&> const_iterator;typedef _list_iterator<T,const T&,const T*> const_iterator;//typedef reverse_Iterator<iterator, T&, T*> reverse_iterator;typedef reverse_Iterator<const_iterator, const T&, const T*> const_reverse_iterator;//构造函数void empty_list(){_head = new Node;_head->_next = _head;_head->_prev = _head;}list(){empty_list();}//list ( list& x);list(const list<T>& s){empty_list();for (auto e : s)//该类型为:T{push_back(e);}}//list& operator= (const list& lt);//传统写法://list<T>& operator= (list<T>& lt)//{//	if(this != &lt)//	{//		//清除*this中内容//		clear();//		for (T e : lt)//		{//			push_back(e);//		}//	}//	return *this;//}//现代写法:list<T>& operator= (list<T> lt){swap(lt);return *this;}//析构函数:void clear(){//区别析构函数,clear只会删除有效数据,保留虚拟头结点iterator it = begin();while (it != end()){it=erase(it);}}~list(){clear();//删除_head;delete _head;_head = nullptr;}//迭代器:iterator begin()//有效第一个节点{//assert(_head->_next != _head);//如果写上面这句,会出现开始为空链表报错情况return _head->_next;}const_iterator begin() const{return _head->_next;}iterator end(){return _head;}const_iterator end() const{return _head;}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin()const{return const_reverse_iterator(end());}const_reverse_iterator rend()const{return const_reverse_iterator(begin());}//常见操作:iterator erase(iterator pos){//检查pos位置非_head位置assert(pos !=end());//删除的是pos位置Node* current = pos._node;Node* prev = current->_prev;Node* next = current->_next;//删除操作prev->_next = next;next->_prev = prev;delete current;return next;//返回的是pos下一个位置}iterator erase(iterator first, iterator last)//区间左闭右开{assert(first != end());assert(last != end());while (first != last){if (first == end())break;first = erase(first);}return first;}void push_back(const T& val){Node* tmp = new Node(val);Node* tail = _head->_prev;tail->_next = tmp;tmp->_prev = tail;tmp->_next = _head;_head->_prev = tmp;}void swap(list<T>& tmp){std::swap(_head, tmp._head);}iterator insert(iterator pos, const T& x){//insert是指在pos位置前插入Node* current = pos._node;Node* prev = current->_prev;//开空间Node* tmp = new Node(x);tmp->_prev = prev;prev->_next = tmp;tmp->_next = current;current->_prev = tmp;//return iterator(tmp);return tmp;//注意点:单参数的类可以隐式类型转换}//容量相关:bool empty() const{return _head->_next == _head;}size_t size() const{size_t n = 0;Node* tmp = _head->_next;while (tmp!=_head){tmp = tmp->_next;n++;}return n;}void push_front(const T& x){this->insert(begin(), x);}void pop_back(){this->erase(--end());}void pop_front(){erase(begin());}//Element access:T& front(){return _head->_next->_val;}const T& front() const{return _head->_next->_val;}T& back(){return _head->_prev->_val;}const T& back() const{return _head->_prev->_val;}private://虚拟头结点:Node* _head;};
}

这里再给大家一组测试用例:

#include <iostream>using namespace std;
#include "vector.h"
#include "list.h"void test_list()
{cx::list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);l.push_back(6);cx::list<int>::reverse_iterator it = l.rbegin();while (it != l.rend()){cout << *it << " ";it++;}cout << endl;
}
void test_vector()
{cx::vector<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);l.push_back(5);l.push_back(6);cx::vector<int>::reverse_iterator it = l.rbegin();while (it != l.rend()){cout << *it << " ";it++;}cout << endl;
}
int main()
{test_list();test_vector();return 0;
}

感谢大家的支持!!!

相关文章:

reverse_iterator实现

对于实现reverse_iterator&#xff0c;我们可以学栈和队列的实现过程&#xff0c;利用适配器&#xff0c;实现如下; #pragma oncetemplate<class Iterator,class Ref,class Ptr> class reverse_Iterator { public://构造函数&#xff1a;reverse_Iterator(Iterator it):…...

C++:什么情况下函数应该声明为纯虚函数

在C中&#xff0c;函数应该在以下情况下声明为纯虚函数&#xff1a; 抽象基类&#xff1a;当你希望定义一个基类&#xff0c;该基类不能被实例化&#xff0c;只能作为其他类的基类时&#xff0c;你应该在基类中声明至少一个纯虚函数。这样的基类被称为抽象基类。纯虚函数通过在…...

【全面了解自然语言处理三大特征提取器】RNN(LSTM)、transformer(注意力机制)、CNN

目录 一 、RNN1.RNN单个cell的结构2.RNN工作原理3.RNN优缺点 二、LSTM1.LSTM单个cell的结构2. LSTM工作原理 三、transformer1 Encoder&#xff08;1&#xff09;position encoding&#xff08;2&#xff09;multi-head-attention&#xff08;3&#xff09;add&norm 残差链…...

区块链推广海外市场怎么做,CloudNEO服务商免费为您定制个性化营销方案

随着区块链技术的不断发展和应用场景的扩大&#xff0c;区块链项目希望能够进入海外市场并取得成功已成为越来越多公司的目标之一。然而&#xff0c;要在海外市场推广区块链项目&#xff0c;需要采取有效的营销策略和措施。作为您的区块链项目营销服务商&#xff0c;CloudNEO将…...

【S5PV210】 | ARM的指令集合

【S5PV210】 | ARM的指令集合 时间&#xff1a;2024年3月17日23:32:06 目录 文章目录 【S5PV210】 | ARM的指令集合目录 ARM指令集具有一系列显著的特点。首先&#xff0c;它属于RISC&#xff08;精简指令集计算机&#xff09;架构&#xff0c;这意味着译码机制相对简单。在AR…...

2024-3-17Go语言入门

在Go语言中&#xff1a; var a chan int 定义了一个名为 a 的变量&#xff0c;其类型为 chan int。这意味着 a 是一个整型值的通道&#xff08;channel&#xff09;。通道是Go语言中用于goroutine之间通信的一种机制&#xff0c;你可以通过通道发送和接收特定类型的值。在这个例…...

AJAX-XMLHttpRequest

XMLHttpRequest 定义&#xff1a; XMLHttpRequest对象用于与服务器交互。通过XMLHttpRequest可以在不断刷新页面的情况下请求特定URL&#xff0c;获取数据。这允许网页在不影响用户操作的情况下&#xff0c;更新页面的局部内容。 关系&#xff1a; axios内部采用XMLHttpReques…...

【GPT-SOVITS-04】SOVITS 模块-鉴别模型解析

说明&#xff1a;该系列文章从本人知乎账号迁入&#xff0c;主要原因是知乎图片附件过于模糊。 知乎专栏地址&#xff1a; 语音生成专栏 系列文章地址&#xff1a; 【GPT-SOVITS-01】源码梳理 【GPT-SOVITS-02】GPT模块解析 【GPT-SOVITS-03】SOVITS 模块-生成模型解析 【G…...

论文阅读_时序模型_iTransformer

1 2 3 4 5 6 7 8英文名称: ITRANSFORMER: INVERTED TRANSFORMERS ARE EFFECTIVE FOR TIME SERIES FORECASTING 中文名称: ITRANSFORMER&#xff1a;倒置Transformers在时间序列预测中的有效性 链接: https://openreview.net/forum?idX6ZmOsTYVs 代码: https://github.com/thum…...

Docker 哲学 - 容器操作 -cp

1、拷贝 容器绑定的 volume的 数据&#xff0c;到指定目录 2、匿名挂载 volume 只定义一个数据咋在容器内的path&#xff0c;docker自动生成一个 sha256 的key作为 volume 名字。这个 sha256 跟 commitID 一致都是唯一的所以 &#xff0c;docker利用这个机制&#xff0c;可以…...

作品展示ETL

1、ETL 作业定义、作业导入、控件拖拽、执行、监控、稽核、告警、报告导出、定时设定 欧洲某国电信系统数据割接作业定义中文页面&#xff08;作业顶层&#xff0c;可切英文&#xff0c;按F1弹当前页面帮助&#xff09; 涉及文件拆分、文件到mysql、库到库、数据清洗、数据转…...

python的集合应用

在Python中&#xff0c;集合是一种无序、可变的数据类型&#xff0c;用于存储不重复的元素。Python提供了内置的集合类型 set&#xff0c;以及 frozenset&#xff08;不可变的集合&#xff09;。以下是一些Python集合的常见应用场景&#xff1a; 去重&#xff1a; 集合是存储唯…...

盒子IM开源仿微信聊天程序源码,可以商用

安装教程 1.安装运行环境 安装node:v14.16.0安装jdk:1.8安装maven:3.6.3安装mysql:5.7,密码分别为root/root,运行sql脚本(脚本在im-platfrom的resources/db目录)安装redis:5.0安装minio&#xff0c;命令端口使用9001&#xff0c;并创建一个名为”box-im”的bucket&#xff0c…...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Web)中篇

onBeforeUnload onBeforeUnload(callback: (event?: { url: string; message: string; result: JsResult }) > boolean) 刷新或关闭场景下&#xff0c;在即将离开当前页面时触发此回调。刷新或关闭当前页面应先通过点击等方式获取焦点&#xff0c;才会触发此回调。 参数…...

静默安装OGG21.3微服务版本FOR ORACLE版本

静默安装OGG21.3微服务版本FOR ORACLE版本 silent install ogg21.3 for oracle 某度找来找去都没有找到一份可靠的静默安装OGG21.3微服务版本的案例&#xff0c;特别难受&#xff0c;为此将自己静默安装的步骤一步步贴出来分享给大家&#xff0c;请指点&#xff0c;谢谢。 至…...

[二分查找]LeetCode2040:两个有序数组的第 K 小乘积

本文涉及的基础知识点 二分查找算法合集 题目 给你两个 从小到大排好序 且下标从 0 开始的整数数组 nums1 和 nums2 以及一个整数 k &#xff0c;请你返回第 k &#xff08;从 1 开始编号&#xff09;小的 nums1[i] * nums2[j] 的乘积&#xff0c;其中 0 < i < nums1.…...

【Godot4.2】颜色完全使用手册

概述 本篇简单汇总Godot中的颜色的构造和使用&#xff0c;内容包括了&#xff1a; RGB、RGBA&#xff0c;HSV以及HTML16进制颜色值、颜色常量等形式构造颜色颜色的运算以及取反、插值用类型化数组、紧缩数组或PNG图片形式存储多个颜色 构造颜色 因为颜色是一种视觉元素&…...

Blocks —— 《Objective-C高级编程 iOS与OS X多线程和内存管理》

目录 Blocks概要什么是BlocksOC转C方法关于几种变量的特点 Blocks模式Block语法Block类型 变量截获局部变量值__block说明符截获的局部变量 Blocks的实现Block的实质 Blocks概要 什么是Blocks Blocks是C语言的扩充功能&#xff0c;即带有局部变量的匿名函数。 顾名思义&#x…...

Python零基础---爬虫技术相关

python 爬虫技术&#xff0c;关于数据相关的拆解&#xff1a; 1.对页面结构的拆解 2.数据包的分析&#xff08;是否加密了参数&#xff09;&#xff08;Md5 aes&#xff09;难易程度&#xff0c;价格 3.对接客户(433,334) # 数据库 CSV 4.结单&#xff08;发一部分数据&a…...

利用 STM32 TIMER 触发 ADC 实现分组转换

1、问题描述 使用 STM32G4 系列芯片开发产品&#xff0c;用到其中一个 ADC 模块的多个通道&#xff0c;他希望使 用 TIMER 来定时触发这几个通道的转换。不过他有两点疑惑。第一&#xff0c;他期望定时器触发这几个 通道是每触发一次则只转换一个通道&#xff0c;这样依次触发…...

机器学习加速宇宙学参数估计:从神经代理模型到贝叶斯推断实战

1. 引言&#xff1a;当宇宙学遇见机器学习&#xff0c;一场静悄悄的效率革命如果你曾尝试用传统的马尔可夫链蒙特卡洛方法去拟合一个包含暗能量状态方程、中微子质量和原初功率谱指数等十几个参数的宇宙学模型&#xff0c;你大概会和我有同样的感受&#xff1a;等待结果的过程&…...

Get Jobs:你的智能求职导航员,让找工作不再像大海捞针

Get Jobs&#xff1a;你的智能求职导航员&#xff0c;让找工作不再像大海捞针 【免费下载链接】get_jobs &#x1f4bc;【AI找工作助手】全平台自动投简历脚本&#xff1a;(boss、前程无忧、猎聘、智联招聘) 项目地址: https://gitcode.com/gh_mirrors/ge/get_jobs 在求…...

Java AI 应用开发实践:基于 Spring Boot 实现 Chat、Memory、RAG 与 Tool Calling

前言 这两年 AI 应用开发非常火&#xff0c;越来越多开发者开始尝试把大模型能力接入到自己的业务系统中&#xff0c;比如智能客服、知识库问答、企业助手、代码助手、数据分析助手等。 不过在实际开发过程中&#xff0c;我发现一个比较明显的问题&#xff1a; 很多 AI 应用框架…...

手把手教你解锁影驰B360M主板隐藏的fTPM 2.0,绕过限制升级Win11(附BIOS修改避坑指南)

解锁影驰B360M主板fTPM 2.0的完整实战手册当Windows 11的升级提示弹出时&#xff0c;许多使用影驰B360M主板的用户发现自己的设备被系统要求拒之门外——原因很简单&#xff1a;主板BIOS中缺少必要的fTPM 2.0支持选项。这并非硬件不支持&#xff0c;而是厂商在固件层面隐藏了相…...

2026年照片去水印免费软件保姆级教程!学会这几招,告别水印烦恼

你是不是也遇到过这样的抓狂时刻&#xff1f;在平台上刷到一张特别适合做壁纸或配图的高清照片&#xff0c;兴冲冲地保存下来&#xff0c;结果角落里的水印瞬间让整张图的格调打了对折&#xff1b;又或者&#xff0c;自己辛辛苦苦做好的图片&#xff0c;在分享转发几道后&#…...

室内点云轮廓提取

1 简介 室内点云轮廓提取是三维感知中的一项基础处理技术,它的核心作用是将杂乱、海量的原始点云,转化为简洁、有意义的几何边界。主要用处体现在以下几个方面: 1 机器人导航与避障 轮廓提取能实时勾勒出墙壁、家具、门窗等障碍物的边缘,帮助扫地机器人、服务机器人快速理…...

SHAP特征选择赋能量子机器学习,高效解决量子相分类难题

1. 项目概述&#xff1a;当量子机器学习遇见可解释AI在量子多体物理和材料科学领域&#xff0c;准确识别和分类物质的量子相是一个基础且极具挑战性的问题。传统的相图绘制依赖于精确求解模型哈密顿量或进行大规模数值模拟&#xff0c;过程复杂且计算成本高昂。近年来&#xff…...

ThriftPy在微服务架构中的应用:企业级RPC服务搭建实战

ThriftPy在微服务架构中的应用&#xff1a;企业级RPC服务搭建实战 【免费下载链接】thriftpy Thriftpy has been deprecated, please migrate to https://github.com/Thriftpy/thriftpy2 项目地址: https://gitcode.com/gh_mirrors/th/thriftpy ThriftPy是一个纯Python实…...

为什么Rotating-machine-fault-data-set是机械故障诊断研究的必备资源?

为什么Rotating-machine-fault-data-set是机械故障诊断研究的必备资源&#xff1f; 【免费下载链接】Rotating-machine-fault-data-set Open rotating mechanical fault datasets (开源旋转机械故障数据集整理) 项目地址: https://gitcode.com/gh_mirrors/ro/Rotating-machin…...

在CentOS7服务器上装Win10?手把手教你用Ventoy搞定双系统(附网卡驱动安装避坑指南)

在CentOS7服务器上实现Win10双系统&#xff1a;Ventoy实战与驱动避坑指南 当Linux服务器遇上Windows需求&#xff0c;双系统成为了一种优雅的解决方案。本文将带你深入探索在CentOS7生产环境中部署Win10双系统的完整流程&#xff0c;特别针对服务器硬件特性提供定制化指导。 …...