当前位置: 首页 > 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;这样依次触发…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...