【cmu15445c++入门】(6)c++的迭代器

news2024/11/15 19:41:14

 一、迭代器

C++ 迭代器是指向容器内元素的对象。它们可用于循环访问该容器的对象。我们知道迭代器的一个示例是指针。指针可用于循环访问 C 样式数组.

二、代码

自己实现一个迭代器

// C++ iterators are objects that point to an element inside a container.
// They can be used to iterate through the objects of that container.
// One example of an iterator that you know is a pointer. A pointer
// can be used to iterate through a C style array. Take the following
// C-style code snippet:
// C++ 迭代器是指向容器内元素的对象。它们可用于循环访问该容器的对象。
// 我们知道迭代器的一个示例是指针。指针可用于循环访问 C 样式数组.


// int *array = malloc(sizeof(int) * 10);
// int *iter = array;
// int zero_elem = *iter;
// iter++;
// int first_elem = *iter;

// As we can see, the ++ operator can be used to iterate through the
// C style array, and the derefence operator returns the value at the
// iterator.

// 正如我们所看到的,++ 运算符可用于遍历 C 样式数组,而引用运算符在迭代器处返回值。

// The main components of a C++ iterator are its main two operators. The
// dereference operator (*) on an iterator should return the value of the
// element at the current position of the iterator. The ++ (postfix increment)
// operator should increment the iterator's position by 1. As you can see, this
// is true with the pointer being used to iterate through a C style array.
// C++迭代器的主要组件是其主要的两个运算符。迭代器上的取引用运算符(*),应返回迭代器当前位置处的元素值。++(后缀增量)运算符应将迭代器的位置递增1。和c语言的用法一样。

// There are a few examples about how to use iterators to access elements
// in C++ STL containers in vectors.cpp, sets.cpp, unordered_maps.cpp, 
// and auto.cpp. This is because using iterators in C++ to access and modify
// elements in C++ STL containers is considered good style, and worth
// mentioning in these files. 

// 有几个示例 vectors.cpp、sets.cpp、unordered_maps.cpp 和 auto.cpp 介绍了如何使用迭代器访问C++STL 容器中的元素。
// 在 C++ 中使用迭代器来访问和修改 C++ STL 容器中的元素被认为是很好的风格,在这些文件中值得一提。

// This file will mainly focus on the implementation of iterators. In this
// file, we demonstrate implementing C++ iterators by writing a basic doubly
// linked list (DLL) iterator.

// Includes std::cout (printing) for demo purposes.
#include <iostream>

// This is the definition of the Node struct, used in our DLL.
struct Node {
  Node(int val) 
    : next_(nullptr)
    , prev_(nullptr)
    , value_(val) {}

  Node* next_;
  Node* prev_;
  int value_;
};

// This class implements a C++ style iterator for the doubly linked list class 
// DLL. This class's constructor takes in a node that marks the start of the
// iterating. It also implements several operators that increment the iterator
// (i.e. accessing the next element in the DLL) and test for equality between
// two different iterators by comparing their curr_ pointers.
class DLLIterator {
  public:
    DLLIterator(Node* head) 
      : curr_(head) {}

    // Implementing a prefix increment operator (++iter).
    DLLIterator& operator++() {
      curr_ = curr_->next_;
      return *this;
    }

    // Implementing a postfix increment operator (iter++). The difference
    // between a prefix and postfix increment operator is the return value
    // of the operator. The prefix operator returns the result of the
    // increment, while the postfix operator returns the iterator before
    // the increment.
    DLLIterator operator++(int) {
      DLLIterator temp = *this;
      ++*this;
      return temp;
    }

    // This is the equality operator for the DLLIterator class. It
    // tests that the current pointers are the same.
    bool operator==(const DLLIterator &itr) const {
      return itr.curr_ == this->curr_;
    }

    // This is the inequality operator for the DLLIterator class. It
    // tests that the current pointers are not the same.
    bool operator!=(const DLLIterator &itr) const {
      return itr.curr_ != this->curr_;
    }

    // This is the dereference operator for the DLLIterator class. It
    // returns the value of the element at the current position of the
    // iterator. The current position of the iterator is marked by curr_,
    // and we can access the value of curr_ by accessing its value field.
    int operator*() {
      return curr_->value_;
    }

  private:
    Node* curr_;
};

// This is a basic implementation of a doubly linked list. It also includes
// iterator functions Begin and End, which return DLLIterators that can be
// used to iterate through this DLL instance.
class DLL {
  public:
    // DLL class constructor.
    DLL() 
    : head_(nullptr)
    , size_(0) {}

    // Destructor should delete all the nodes by iterating through them.
    ~DLL() {
      Node *current = head_;
      while(current != nullptr) {
        Node *next = current->next_;
        delete current;
        current = next;
      }
      head_ = nullptr;
    }

    // Function for inserting val at the head of the DLL.
    void InsertAtHead(int val) {
      Node *new_node = new Node(val);
      new_node->next_ = head_;

      if (head_ != nullptr) {
        head_->prev_ = new_node;
      }

      head_ = new_node;
      size_ += 1;
    }

    // The Begin() function returns an iterator to the head of the DLL,
    // which is the first element to access when iterating through.
    DLLIterator Begin() {
      return DLLIterator(head_);
    }

    // The End() function returns an iterator that marks the one-past-the-last
    // element of the iterator. In this case, this would be an iterator with
    // its current pointer set to nullptr.
    DLLIterator End() {
      return DLLIterator(nullptr);
    }

    Node* head_{nullptr};
    size_t size_;
};

// The main function shows the usage of the DLL iterator.
int main() {
  // Creating a DLL and inserting elements into it.
  DLL dll;
  dll.InsertAtHead(6);
  dll.InsertAtHead(5);
  dll.InsertAtHead(4);
  dll.InsertAtHead(3);
  dll.InsertAtHead(2);
  dll.InsertAtHead(1);

  // We can iterate through our DLL via both our prefix and postfix operators.
  std::cout << "Printing elements of the DLL dll via prefix increment operator\n";
  for (DLLIterator iter = dll.Begin(); iter != dll.End(); ++iter) {
    std::cout << *iter << " ";
  }
  std::cout << std::endl;

  std::cout << "Printing elements of the DLL dll via postfix increment operator\n";
  for (DLLIterator iter = dll.Begin(); iter != dll.End(); iter++) {
    std::cout << *iter << " ";
  }
  std::cout << std::endl;

  return 0;
}

三、运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1436710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光学PCIe 6.0技术引领AI时代超大规模集群

随着云计算、大数据和人工智能技术的快速发展&#xff0c;超大规模数据中心正经历一场前所未有的变革。传统的集中式架构逐渐转变为解聚式&#xff08;disaggregated&#xff09;架构&#xff0c;这种架构将计算、存储和网络资源从单一的物理服务器中分离出来&#xff0c;形成独…

CSS实践调研,行业流行的CSS代码风格

案例1 Taro中的组件 以下为ScrollView组件的样式&#xff08;更新时间为2024年1月&#xff09;&#xff1a; taro的 image组件&#xff08;更新时间为3年前&#xff09;&#xff1a; 案例2&#xff1a; vantui 的Button组件 案例3&#xff1a;elementui的slider组件 案例4…

十分钟GIS——geoserver+postgis+udig从零开始发布地图服务

1数据库部署 1.1PostgreSql安装 下载到安装文件后&#xff08;postgresql-9.2.19-1-windows-x64.exe&#xff09;&#xff0c;双击安装。 指定安装目录&#xff0c;如下图所示 指定数据库文件存放目录位置&#xff0c;如下图所示 指定数据库访问管理员密码&#xff0c;如下图所…

泛型、Trait 和生命周期(上)

目录 1、提取函数来减少重复 2、在函数定义中使用泛型 3、结构体定义中的泛型 4、枚举定义中的泛型 5、方法定义中的泛型 6、泛型代码的性能 每一门编程语言都有高效处理重复概念的工具。在 Rust 中其工具之一就是 泛型&#xff08;generics&#xff09;。泛型是具体类型…

点燃设计之魂,展现艺术力量:NCDA邀你参赛!

未来设计师全国高校数字艺术设计大赛&#xff08;NCDA&#xff09;教育部中国高等教育协会认定&#xff0c;由工业和信息化部人才交流中心主办&#xff0c;教育部发文支持“学习强国”学习平台&#xff0c;与联合国国际大赛对接。比赛始于2012年&#xff0c;每年举行一次&#…

LLM Agents 的细分技术

2.1 RAG&#xff1a;知识&#xff0c;记忆与技能库 2.1.1 RAG简介 RAG的核心思想就是将传统的语言生成模型&#xff08;如GPT系列&#xff09;与一个检索系统相结合&#xff0c;在处理一个输入时&#xff0c;RAG首先使用检索系统从一个大规模的文档集合中检索出相关的文本片段…

算法练习-四数之和(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;数组 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨在…

【算法与数据结构】718、1143、1035、392、115、LeetCode最长重复子数组+最长公共子序列+不相交的线+判断子序列+不同的子序列

文章目录 一、718、最长重复子数组二、1143、最长公共子序列三、1035、不相交的线四、392、判断子序列五、115、不同的子序列六、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、718、最长重复子数组 思路分析&#xff1…

vue3-内置组件-TransitionGroup

<TransitionGroup> 是一个内置组件&#xff0c;用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。 与 <Transition> 的区别 <TransitionGroup> 支持和 <Transition> 基本相同的 props、CSS 过渡 class 和 JavaScript 钩子监听器&…

Linux联网安装MySQL Server

yum安装 以下代码复制粘贴到控制台即可 yum list | grep mysql-server #查看可以下载的MySQLyum install -y mysql-server #安装MySQLmysql_secure_installation #引导安装 引导安装实例如下 systemctl enable mysqld 设置开机自动启动 systemctl sta…

重生奇迹MU冰风谷雪人王

奇迹雪人王刷怪点在哪里 冰风谷&#xff1a;就一个刷怪点&#xff0c;这里还是比较适合走动打怪&#xff0c;这里刷新4只雪人王&#xff0c;这里从100来级挂到200级问题不大。一般来说冰风谷的雪人王以及雪人王以上的怪都有一定几率会掉宝石,去血色、广场还有寺院掉的要多,不固…

XxlJob深度性能优化实践

一、背景 天画项目的数据工厂目前在与xxl-job对接自动化数据生成任务,另外我司也在使用该组件做业务,所以想深入了解下XxlJob。在跟进了社区的github等仓库issue发现开发迭代停滞了一段时间,思来想去准备开个下游分支做一些性能优化和特性开发等,于是fork了下源码,将其作…

环境配置:ROS melodic安装turtlebot

文章目录 1.已有的环境2.安装2.1.首先cd进入到catkin_ws文件夹&#xff0c;然后输入以下命令行&#xff1a;2.2.将turtlebot加入环境2.3.选择性安装其它依赖包2.4.运行turtlebot in stage [perfect] 1.已有的环境 在之前已经配置好了小乌龟的前提下&#xff0c;我们已经拥有了…

2024/2/4 备战蓝桥杯 5-1 前缀和

目录 求和 0求和 - 蓝桥云课 (lanqiao.cn) 可获得的最小取值 0可获得的最小取值 - 蓝桥云课 (lanqiao.cn) 领地选择 P2004 领地选择 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 求和 0求和 - 蓝桥云课 (lanqiao.cn) 思路&#xff1a;先对公式进行合并同类相&#x…

AVR 328pb触摸功能基本介绍和使用

AVR 328pb触摸功能基本介绍和使用 &#x1f4dd;ATMEGA328PB-AU外设中带外围触摸控制器&#xff08;PTC&#xff09;电容式触摸按钮、滑块和轮子24个自帽通道和144个互帽通道。&#xff08;ATMEGA328P没有的&#xff09; ✅PTC-外围触摸控制器 &#x1f343;低功耗、高灵敏度、…

图形界面基础

X Window System 什么是 X Window System&#xff1f; 最初是1984年麻省理工学院的研究&#xff0c;之后变成UNIX、类UNIX、以及OpenVMS等操作系统所一致适用的标准化软体工具套件及显示架构的运作协定。X Window系统透过软体工具及架构协定来建立操作系统所用的图形用户界面&a…

Flink SQL Client 安装各类 Connector、Format 组件的方法汇总(持续更新中....)

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

Redis-布隆过滤器解决穿透详解

本文已收录于专栏 《中间件合集》 目录 背景介绍概念说明原理说明解决穿透安装使用安装过程Redis为普通安装的配置方式Redis为Docker镜像安装的配置方式 具体使用控制台操作命令说明Spring Boot集成布隆过滤器 总结提升 背景介绍 布隆过滤器可以帮助我们解决Redis缓存雪崩的问题…

算法笔记刷题日记——3.简单入门模拟 3.2 查找元素

刷题日记 3.2 查找元素 B1041 B1004 B1028 B1032 A1011 A1006 A1036 错题记录 B1028 人口普查 某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的&#xff0c;但不一定是合理的…

Javascript入门学(基础)

软件篇 JS基础语法第一天 1.javascript介绍 1.1 js是什么 是什么 是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互效果&#xff0c;而html和css是标记性语言&#xff0c;并非编程语言有什么用 js的组成 htmlcssjs实现按钮点击功能 …