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

 一、迭代器

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;
}

三、运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

*s是什么意思

&s是地址&#xff0c;*是指针&#xff0c;*&s是指指向&s地址的指针&#xff1b; j *&s 就是 j s的意思。 例如&#xff1a;readRawData( (char *)& rowCount, sizeof(qint16)); //读取文本流中的行数到rowCount、列数到colCount qint16 rowCount, col…

BVH动画绑骨蒙皮并在Unity上展示

文章目录 Blender绑定骨骼Blender蒙皮Blender中导入bvh文件将FBX导入Unity Blender绑定骨骼 先左上角红框进入model模式&#xff0c;选中要绑定的模型&#xff0c;然后进入Edit模式把骨骼和关节对齐。 &#xff08;选中骨骼&#xff0c;G移动&#xff0c;R旋转&#xff09; 为…

如何进行游戏服务器的负载均衡和扩展性设计?

​在进行游戏服务器的负载均衡和扩展性设计时&#xff0c;需要考虑多个方面&#xff0c;以确保服务器的稳定性和可扩展性。以下是一些关键的步骤和考虑因素&#xff1a; 负载均衡的需求分析 在进行负载均衡设计之前&#xff0c;需要深入了解游戏服务器的负载特性和需求。这包括…

牛客“迎新春,过大年”多校程序设计竞赛A题

题目描述&#xff1a; 这里有个小trick 当时也看到数据范围的问题了 n 是 1 e 6 ∑ i 1 n a [ i ] < 5 e 7 n是1e6 \quad \sum_{i1}^na[i]<5e7 n是1e6∑i1n​a[i]<5e7 我们考虑不同的数 1 2 . . . k − 1 k 1 \quad 2 \quad ... k-1 \quad k 12...k−1k s u m …

ChatGPT论文指南|ChatGPT论文写作过程中6个润色与查重提示词

论文完成初稿之后&#xff0c;一般情况下&#xff0c;宝子们还需要找专家给我们提出评审意见。找专家评审其实并不容易&#xff0c;即使对老师来说&#xff0c;找人评审论文也是一件苦活。我们这个时候可以通过文字提示让 ChatGPT充当我们的评审专家&#xff0c;为论文提出问题…

车位检测,YOLOV8,OPENCV调用

车位检测YOLOV8NANO,opencv调用 车位检测&#xff0c;YOLOV8NANO&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON,ANDROID

macbookpro和macbookair的区别?cleanmymac 怎么清理mac空间

苹果mac air和pro区别有&#xff1a;1、air采用了轻薄的设计&#xff0c;重量相对较轻&#xff0c;便于携带&#xff0c;而pro更加注重性能&#xff0c;所以比较重&#xff1b;2、air通常搭载较低功耗的处理器内存和存储容量相对较小&#xff0c;而pro配备了更强大的处理器、更…

HarmonyOS 鸿蒙应用开发(九、还是蓝海,如何贡献第三方库)

快来共享第三方库吧&#xff0c;不但可以通过分享自己的成果&#xff0c;可以获得来自全球开发者的技术反馈和建议&#xff0c;提升自身技术能力&#xff0c;还有助于提高个人或团队在开源社区中的知名度和影响力。在流量时代和粉丝经济时代&#xff0c;获得曝光度和流量密码。…

HarmonyOS鸿蒙ArkTS证件照生成模板(适合二次开发,全套源码版)

预览效果 部分代码 开发语言 HarmonyOS 鸿蒙 ArkTS语言 &#xff08;Stage模型&#xff09; 备注 一键生成&#xff0c;自带证件照数集&#xff0c; 为开发者带来二次开发和学习体验&#xff0c; 在这祝福开发者们使用愉快。 使用方法 下载后通过DevEco Studio开发工…

腾讯云游戏服务器配置有哪些?

2024年更新腾讯云游戏联机服务器配置价格表&#xff0c;可用于搭建幻兽帕鲁、雾锁王国等游戏服务器&#xff0c;游戏服务器配置可选4核16G12M、8核32G22M、4核32G10M、16核64G35M、4核16G14M等配置&#xff0c;可以选择轻量应用服务器和云服务器CVM内存型MA3或标准型SA2实例&am…

软考21-上午题-数组、矩阵

数组&#xff1a;一组地址连续的空间。 数组是定长线性表在维数上的扩展&#xff0c;即&#xff0c;线性表中的元素又是一个线性表。 一、数组 数组的特点&#xff1a; 数组数目固定&#xff0c;一旦定义了数组结构&#xff0c;不再有元素个数的增减变化。因此&#xff0c;数…

寒假作业-day4

1>请编程实现哈希表的创建存储数组{12,24,234,234,23,234,23}&#xff0c;输入key查找的值&#xff0c;实现查找功能。 代码&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> typedef int datatype; type…

解决Python xlwings报错AttributeError ‘NoneType‘ object has no attribute apps

一、问题背景 今天&#xff0c;遇到了一个问题&#xff1a;以前调试好的python使用xlwings操作wps表格的脚本突然不能运行了&#xff0c;遇到了很多莫名问题&#xff0c;下面记录分享下&#xff1a; 开始报错如下&#xff1a; D:\PycharmProjects\tiku\venv\Scripts\python.e…

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏11(附项目源码)

本节最终效果演示 文章目录 本节最终效果演示系列目录前言选中效果 快捷栏显示对应的手臂工具源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中&#xff0c;我们将探索如何制作…

深度学习缝模块怎么描述创新点?(附写作模板+涨点论文)

深度学习缝了别的模块怎么描述创新点、怎么讲故事写成一篇优质论文&#xff1f; 简单框架&#xff1a;描述自己这个领域&#xff0c;该领域出现了什么问题&#xff0c;你用了什么方法解决&#xff0c;你的方法有了多大的性能提升。 其中&#xff0c;重点讲清楚这两点&#xf…

【Qt Design】界面介绍

文章目录 前言Widget Box&#xff08;工具箱&#xff09;对象查看器Qt Design属性编译器sizePolicy内容 信号/槽编辑器资源浏览器ui文件 前言 Widget Box&#xff08;工具箱&#xff09; 提供很多控件 对象查看器 对象查看区域&#xff0c;可以查看主窗口放置对象的列表 …

力扣面试题 05.03. 翻转数位(前、后缀和)

Problem: 面试题 05.03. 翻转数位 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.将十进制数转换为二进制数&#xff08;每次按位与1求与&#xff0c;并且右移&#xff09;&#xff1b; 2.依次求取二进制数中每一位的前缀1的数量和&#xff0c;和后缀1的数量和…

MongoDB的操作和理解

什么是MongoDB? MongoDB&#xff1a;基于分布式文件存储的数据库由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库(nosql)之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。 Mo…

Webshell一句话木马

一、webshell介绍&#xff08;网页木马&#xff09; 分类&#xff1a; 大马&#xff1a;体积大、隐蔽性差、功能多 小马&#xff1a;体积小&#xff0c;隐蔽强&#xff0c;功能少 一句话木马&#xff1a;代码简短&#xff0c;灵活多样 二、一句话木马&#xff1a; &#xff1a;…

Java开发IntelliJ IDEA2023

IntelliJ IDEA 2023是一款强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为Java开发人员设计。它提供了许多特色功能&#xff0c;帮助开发人员更高效地编写、测试和调试Java应用程序。以下是一些IntelliJ IDEA 2023的特色功能&#xff1a; 智能代码编辑器&…