面试之快速学习STL-迭代适配器
先放一张大图
参考:http://c.biancheng.net/view/7255.html
1. 反向迭代器
例子:
std::list<int> values{1,2,3,4,5};auto start_it = values.rbegin();const auto end_it = values.rend();//start_it end_it std::reverse_iterator<std::list<int>>::iteratorwhile (start_it != end_it) {std::cout << *start_it << std::endl;++start_it;}/*54321*/
- 想使用反向迭代器实现逆序遍历容器,则该容器的迭代器类型必须是双向迭代器或者随机访问迭代器。
- 常见操作
std::vector<int> values{1,2,3,4,5};auto r_start_it = values.rbegin();const auto end_it = values.rend();//r_start_it end_it std::reverse_iterator<std::list<int>>::iteratorwhile (r_start_it != end_it) {std::cout << *r_start_it << std::endl;++r_start_it;}/*54321*/r_start_it = values.rbegin();std::cout << "r_start_it + 3 = " << *(r_start_it + 3)<< std::endl;std::cout << "r_start_it[3] = " << r_start_it[3] << std::endl;
- 注意这里不能用std::list,因为它是双向迭代器, +3的操作需要随机访问迭代器。故联想到std::list排序只能使用list提供的 sort 接口,而不能使用algorithm 提供的 sort 接口,因为链表的物理地址不连续,迭代器为双向迭代器,不支持 + - 操作,而算法库中的 sort 接口需要支撑 + - 的随机迭代器;
2. 插入迭代器适配器
感觉没啥好讲的,看看代码:
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main() {//创建一个 vector 容器std::vector<int> foo;//创建一个可向 foo 容器尾部添加新元素的迭代器std::back_insert_iterator< std::vector<int> > back_it(foo);//将 5 插入到 foo 的末尾back_it = 5;//将 4 插入到当前 foo 的末尾back_it = 4;//将 3 插入到当前 foo 的末尾back_it = 3;//将 6 插入到当前 foo 的末尾back_it = 6;//输出 foo 容器中的元素for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)std::cout << *it << ' ';return 0;/*5 4 3 6*/
}
- 每次插入新元素时,该元素都会插入到当前 foo 容器的末尾。换句话说,程序中 11-17 行的每个赋值语句,都可以分解为以下这 2 行代码:
//pos表示指向容器尾部的迭代器,value 表示要插入的元素
pos = foo.insert(pos,value);
++pos;
3. istream_iterator和ostream_iterator
原理源码:原理
- 自己理解:istream_iterator是重载了++操作符然后调用的是read(); ostream_iterator重载 = 操作符,做输出操作。
#include <iostream>
#include <thread>
#include <vector>
#include <numeric>
#include <algorithm>
#include <cstring>
#include <deque>
#include <iterator>
using namespace std;int main()
{deque<int> id;istream_iterator<int> intie(cin),eos; //开始触发一次输入 copy(intie, eos, inserter(id, id.begin())); //迭代器类型为InputIterator,所以这里调用copy的时候采用*result = *first;版本,会使用重载类型 ,那么就会转换为插入操作 //其中++first会继续调用下一个,然后重载为新的输入ostream_iterator<int> outie(cout, " "); //deque的迭代器类型为random_access_iterator,也会是 *result = *first;调用赋值操作 result++操作,返回本身,不影响后面的输出操作copy(id.begin(), id.end(), outie); //将=操作,转换为输出操作cout << endl;system("pause");
}
3. 移动迭代器
std::vector<std::string> v1{ "haha", "xixi" };//调用移动构造函数std::vector<std::string> v2(make_move_iterator(v1.begin()), make_move_iterator(v1.end()));std::cout << "v1 : " << std::endl;for (auto record : v1)std::cout << record << std::endl;std::cout << "v2 : " << std::endl;for (auto record : v2)std::cout << record << std::endl;/*v1 :v2 : hahaxixi*/
没啥好说的,就是每个值调用移动构造函数make_move_iterator
4. advance()函数用法详解
template <class InputIterator, class Distance>
void advance (InputIterator& it, Distance n);
- 根据 it 类型是否为随机访问迭代器,advance() 函数底层采用了不同的实现机制:
当 it 为随机访问迭代器时,由于该类型迭代器支持 p+n 或者 p-n(其中 p 就是一个随机访问迭代器)运算,advance() 函数底层采用的就是 it+n 操作实现的;
当 it 为其他类型迭代器时,它们仅支持进行 ++ 或者 – 运算,这种情况下,advance() 函数底层是通过重复执行 n 个 ++ 或者 – 操作实现的。
#include <iostream> // std::cout
#include <iterator> // std::advance
#include <forward_list>
using namespace std;
int main() {//创建一个 forward_list 容器forward_list<int> mylist{1,2,3,4};//it为前向迭代器,其指向 mylist 容器中第一个元素forward_list<int>::iterator it = mylist.begin();//借助 advance() 函数将 it 迭代器前进 2 个位置advance(it, 2);cout << "*it = " << *it;return 0;
}
注意: 此程序中,由于 it 为前向迭代器,其只能进行 ++ 操作,即只能前进(右移),所以 advance() 函数的第 2 个参数只能为正数。
5. distance()函数用法详解
template
typename iterator_traits::difference_type distance (InputIterator first, InputIterator last);
- first 和 last 的迭代器类型,直接决定了 distance() 函数底层的实现机制:
当 first 和 last 为随机访问迭代器时,distance() 底层直接采用 last - first 求得 [first, last) 范围内包含元素的个数,其时间复杂度为O(1)常数阶;
当 first 和 last 为非随机访问迭代器时,**distance() 底层通过不断执行 ++first(或者 first++)直到 first==last,**由此来获取 [first, last) 范围内包含元素的个数,其时间复杂度为O(n)线性阶。
#include <iostream> // std::cout
#include <iterator> // std::distance
#include <list> // std::list
using namespace std;int main() {//创建一个空 list 容器list<int> mylist;//向空 list 容器中添加元素 0~9for (int i = 0; i < 10; i++) {mylist.push_back(i);}//指定 2 个双向迭代器,用于执行某个区间list<int>::iterator first = mylist.begin();//指向元素 0list<int>::iterator last = mylist.end();//指向元素 9 之后的位置//获取 [first,last) 范围内包含元素的个数cout << "distance() = " << distance(first, last);return 0;
}
相关文章:

面试之快速学习STL-迭代适配器
先放一张大图 参考:http://c.biancheng.net/view/7255.html 1. 反向迭代器 例子: std::list<int> values{1,2,3,4,5};auto start_it values.rbegin();const auto end_it values.rend();//start_it end_it std::reverse_iterator<std::lis…...

【Linux】【驱动】杂项设备驱动
【Linux】【驱动】杂项设备驱动 Linux三大设备驱动1. 我们这节课要讲的杂项设备驱动是属于我们这三大设备驱动里面的哪个呢?2.杂项设备除了比字符设备代码简单,还有别的区别吗?3.主设备号和次设备号是什么? 挂载驱动 杂项设备驱动是字符设备驱动的一种࿰…...

【HCIP】10.路由策略
📎13 路由策略与路由控制.pptx 通过修改路由的属性,影响了路由的生成及选路,最终影响了转发流量的路径;控制平面。 ACL IP prefix Filter-Policy Router-Policy 笔记...

【腾讯云Cloud Studio实战训练营】使用Cloud Studio社区版快速构建React完成点餐H5页面还原
陈老老老板🦸 👨💻本文专栏:生活(主要讲一下自己生活相关的内容) 👨💻本文简述:生活就像海洋,只有意志坚强的人,才能到达彼岸。 👨💻上一篇…...

测试开发工程必备技能之一:Mock的使用
1. 背景 在实际产品开发过程中,某个服务或前端依赖一个服务接口,该接口可能依赖多个底层服务或模块,或第三方接口,比如说服务 A 依赖服务B,服务B又依赖服务 C 这种依赖的问题会导致原本的需求目的是要验证服务A&…...

Qbytearray:从十六进制字符串转字节一些注意事项
1、从十六进制字符串转字节后,按字节使用时 QByteArray data QByteArray::fromHex("cc94");printf("%x %x\n",data.at(0),data.at(0)&0xff);//若超过127,会不一样printf("%d %d\n",data.at(0),data.at(0)&0xff);…...

【Docker】Docker的使用案例以及未来发展、Docker Hub 服务、环境安全的详细讲解
前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...
Redis有哪几种内存淘汰策略?
推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 https://dr…...

操作系统练习:在Linux上创建进程,及查看进程状态
说明 进程在执行过程中可以创建多个新的进程。创建进程称为“父进程”,新的进程称为“子进程”。每个新的进程可以再创建其他进程,从而形成进程树。 每个进程都有一个唯一的进程标识符(process identifier,pid)。在L…...

Java虚拟机(JVM):垃圾收集算法
目录 一、分代收集理论 二、标记-清除算法 三、标记-复制算法 四、标记-整理算法 一、分代收集理论 分代收集理论建立在两个分代假说之上: 1、弱分代假说:绝大多数对象都是朝生夕灭的。 2、强分代假说:熬过越多次垃圾收集过程的对象就…...
【爬虫】Requests库的使用
这个库比我们上次说的 urllib 可是要牛逼一丢丢的。通过它我们可以用更少的代码,模拟浏览器操作。 不多说,直接上手代码。 requests 常见用法 mport requests# get请求网站 r requests.get(https://www.baidu.com/) # 获取服务器响应文本内容 r.text …...

了解生成对抗网络 (GAN)
一、介绍 Yann LeCun将其描述为“过去10年来机器学习中最有趣的想法”。当然,来自深度学习领域如此杰出的研究人员的赞美总是对我们谈论的主题的一个很好的广告!事实上,生成对抗网络(简称GAN)自2014年由Ian J. Goodfel…...

opencv-人脸关键点定位
#导入工具包 from collections import OrderedDict import numpy as np import argparse import dlib import cv2#https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/ #http://dlib.net/files/# 参数 ap argparse.ArgumentParser() ap.add_argument("-p&quo…...
言语理解与表达 郭熙(一)
40题 35min 逻辑填空 (20题) 题型:实词填空;成语填空;混搭填空 解题思路 词义辨析:词义侧重;固定搭配;程度较重;感情色彩 语境分析: 关联关系ÿ…...

【stable-diffusion使用扩展+插件和模型资源(上】
文章目录 前言一、插件推荐1.qrcode-monster2.sd-webui-openpose-editor3.sd-webui-depth-lib4.roop(换脸插件)5.sd-webui-qrcode-toolkit(艺术二维码)5.光源控制6.二次元转真人7.动态视频转场(loopback-waveÿ…...

面试之快速学习STL-无序关联式容器
和关联式容器一样,无序容器也使用键值对(pair 类型)的方式存储数据。不过,本教程将二者分开进行讲解,因为它们有本质上的不同: 关联式容器的底层实现采用的树存储结构,更确切的说是红黑树结构&a…...

C++线程库
C线程库是C11新增的重要的技术之一,接下来来简单学习一下吧! thread类常用接口 函数名功能thread()构造一个线程对象,没有关联任何线程函数,即没有启动任何线程。thread(fn, args1, args2, ...)构造一个线程对象,并…...

一文看懂群晖 NAS 安装 Mysql 远程访问连接
文章目录 1. 安装Mysql2. 安装phpMyAdmin3. 修改User 表4. 本地测试连接5. 安装cpolar6. 配置公网访问地址7. 固定连接公网地址 群晖安装MySQL具有高效、安全、可靠、灵活等优势,可以为用户提供一个优秀的数据管理和分析环境。同时具有良好的硬件性能和稳定性&#…...

永久设置pip指定国内镜像源(windows内)
1.首先列出国内四个镜像源网站: 一、清华源 https://pypi.tuna.tsinghua.edu.cn/simple/ 二、阿里源 https://mirrors.aliyun.com/pypi/simple 三、中科大源 https://pypi.mirrors.ustc.edu.cn/simple/ 四、豆瓣源 http://pypi.douban.com/simple/ 2.一般下载所需要…...
【SA8295P 源码分析】27 - QNX Ethernet MAC 驱动 之 emac_tx_thread_handler 数据发送线程 源码分析
【SA8295P 源码分析】27 - QNX Ethernet MAC 驱动 之 emac_tx_thread_handler 数据发送线程 源码分析 系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》 本文链接:《【SA8295P 源码分析】27 - QNX Ethernet MAC 驱动 之 emac_tx_thread_handler() 数据发送线程…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...

Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...