【C++ STL】string类-----迭代器(什么是迭代器?迭代器分哪几类?迭代器的接口如何使用?)

2023-11-21 01:28

本文主要是介绍【C++ STL】string类-----迭代器(什么是迭代器?迭代器分哪几类?迭代器的接口如何使用?),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、前言

二、什么是迭代器 

 三、迭代器的分类与接口

💦迭代器的分类 

 💦迭代器的接口

  💦迭代器与接口之间的关联

 四、string类中迭代器的应用

💦 定义string类----迭代器 

 💦string类中迭代器进行遍历

✨begin+end 正向(可读可修改)迭代器 

 ✨begin+end 正向(只读)迭代器 

 ✨rbegin+rend 反向(可读可修改)迭代器 

 ✨rbegin+rend 反向(只读)迭代器 

 💦string 类中迭代器在算法上的应用

 ✨【reverse】函数

 ✨【sort】函数

五、共勉 


一、前言

       在C++中,标准模板库(Standard Template Library,STL)是一组强大的通用模板类和函数,它为我们提供了很多供使用的数据结构和算法。其中,string类是STL中一个非常有用的类,用于处理字符串。在使用string类时,我们经常需要遍历字符串的每个字符或者进行某些特定的操作。而实现遍历和操作的关键就是使用string迭代器。本文将详细介绍string迭代器的使用方法及其在处理字符串时的重要作用。

二、什么是迭代器 

       当我们需要遍历一个集合(比如数组、列表或字符串)中的元素时,就像是访问看每个元素,这时候迭代器就派上用场了。迭代器就像是一个指针,它可以帮助我们在集合中逐个地获取其中的元素,并且可以根据需要进行修改。你可以把迭代器想象成一个遥控器,可以让我们在集合中前进、后退,或者指向特定的元素。使用迭代器,我们不需要关心集合内部的具体实现细节,只需要专注于每个元素的访问和操作。

       迭代器提供了一种抽象的方法来处理集合中的元素,它可以让我们在遍历过程中轻松访问每个元素,而不必担心底层数据结构是什么样的。迭代器分为不同的类型,每种类型有着特定的目的和功能。例如,我们可以使用迭代器来读取集合元素的值,也可以使用迭代器来修改元素的值,甚至可以删除或添加元素。


       总的来说,迭代器是一种工具,帮助我们在集合中按照一定的顺序遍历和操作每个元素,使得我们能够更方便地处理集合中的数据使用迭代器,我们可以以一种统一的方式处理不同类型的集合,提高了代码的可复用性和灵活性。

      所以本次博客将以string类为例,来详细的讲解迭代器!!
 

 三、迭代器的分类与接口

💦迭代器的分类 

         迭代器总共有四种:正向迭代器(iterator)、反向迭代器(reverse_iterator)、只读迭代器(const_iterator)、只读反向迭代器(const_reverse_iterator);


      当我们有针对const修饰的对象时,则必须使用只读迭代器const_iterator



        迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。

       不同容器底层数据结构不一样,每一种容器都有自己的迭代器,迭代器按照定义方式分成以下四种:
1.正向迭代器,定义方法如下:

容器类名::iterator  迭代器名;

2.常量正向迭代器,定义方法如下:

容器类名::const_iterator  迭代器名;

3. 反向迭代器,定义方法如下:

容器类名::reverse_iterator  迭代器名;

4.常量反向迭代器,定义方法如下:

容器类名::const_reverse_iterator  迭代器名;

 💦迭代器的接口

        迭代器的接口总共有8种,但是最常用的是4种,所以本次博客来讲解最常用的4种接口的用法


常用接口的用法描述:

函数名称功能说明
1. begin正向迭代器返回容器 c 的第一个元素
2. end正向迭代器返回容器 c 的最后一个元素的后一个位置
3. rbegin返回一个逆序迭代器,它指向容器 c 的最后一个元素
4. rend返回一个逆序迭代器,它指向容器 c 的第一个元素的前面位置

  💦迭代器与接口之间的关联

1. 接口 begin 和 end 属于正向迭代器的接口

2.接口 rbegin 和 rend 属于反向迭代器的接口

 

 四、string类中迭代器的应用

💦 定义string类----迭代器 

string::iterator ite;

为什么要这样定义呢?

这一点我们需要深入考虑迭代器的底层原理,迭代器是如何被设计的,看如下代码:

typedef char* iterator;
typedef const char* const_iterator;
iterator begin()
{return _str;
}iterator end()
{return _str + _size;
}

从上述代码中我们发现,迭代器 iterator 其实是在string 类中 的 char*  字符指针  类型  的别名 所以定义的 ite 就是一个字符指针。


观察代码我们发现迭代器的用法和地址很像,上面也说了可以看成指针,所有迭代器是指针吗?

迭代器不完全是指针

某些类的迭代器底层是指针,如string,但是有些类的迭代器底层并不是指针,但在理解上可以看成指针。

 💦string类中迭代器进行遍历

理解

当我们说到迭代器时,可以将其想象为一个类似于指针的对象,它允许我们在容器(例如字符串)中按顺序访问元素或字符。

对于字符串(std::string),我们可以使用迭代器来遍历其中的字符。迭代器可以帮助我们逐个访问字符串中的每个字符,从头到尾,或者反向从尾到头。

想象一下,你有一串字母,比如 “Hello”,可以将迭代器看作是一根指向字符的手指。开始时,指向字符串的开头,即 ‘H’。然后,你可以通过移动指针(迭代器)来访问下一个字符,指向 ‘e’,再移动指针指向 ‘l’,以此类推,直到访问到最后一个字符 ‘o’。

✨begin+end 正向(可读可修改)迭代器 

 使用迭代器,去遍历一个字符串,代码如下:

int main()
{string s("hello");string::iterator ite;for (ite = s.begin(); ite != s.end(); ite++){(*ite)++;cout << *ite << " ";}cout << endl;return 0;
}



⚡ 细节解析:

        begin是返回字符串第一个字符的迭代器,而end则是返回一个指向字符串后一个字符的迭代器。注意,end返回的是指向字符的下一个字符的迭代器。C++中的迭代器一般是左闭右开区间。

 ✨begin+end 正向(只读)迭代器 

 使用迭代器,去遍历一个字符串,代码如下:

void Func(const string& s)
{string::iterator ite = s.begin();while (ite != s.end()){cout << *ite << " ";ite++;}cout << endl;
}int main()
{string s("hello");Func(s);return 0;
}


     原因就是在于对象s是属于const对象,那么它在调用【begin】的时候返回的就是const迭代器,是【只读】那此时我们若是使用普通迭代去接收的话就是【可读可写】,也算是一个权限放大的问题

代码修改:

void Func(const string& s)
{string::const_iterator ite = s.begin();while (ite != s.end()){cout << *ite << " ";ite++;}cout << endl;
}int main()
{string s("hello");Func(s);return 0;
}

 ✨rbegin+rend 反向(可读可修改)迭代器 

  使用迭代器,去遍历一个字符串并反向输出,代码如下:

int main()
{string s("hello");cout << s << endl << endl;string::reverse_iterator rit;for (rit = s.rbegin(); rit != s.rend(); rit++){(*rit)++;cout << *rit << " ";}cout << endl;return 0;
}

⚡ 细节解析:
        我们发现,反向迭代器输出的是正向迭代器相反的结果。在反向迭代器中,rbegin指向字符串的最后一个字符(即字符串的反向开头)。rend返回一个反向迭代器,指向字符串第一个字符(被认为是字符串的反向端)前面的理论元素。正向迭代器与反向迭代器的不同还在于,正向迭代器的++是向尾部走的,而反向迭代器则向头部走。

 

 ✨rbegin+rend 反向(只读)迭代器 

  使用迭代器,去遍历一个字符串并反向输出,代码如下:

void Func(const string& s)
{string::const_reverse_iterator ite = s.rbegin();while (ite != s.rend()){cout << *ite << " ";ite++;}cout << endl;
}int main()
{string s("hello");Func(s);return 0;
}

 💦string 类中迭代器在算法上的应用

 ✨【reverse】函数

  • 首先就是我们使用到最多的【reverse】函数,字面意思:颠倒元素

  • 观察其参数我们可以发现,传入两个迭代器即可,那刚好就是我们前面所学的【begin】和【end】
reverse(s.begin(), s.end());
  • 一起来看一下结果就可以发现确实string字符串内的字符都发生了一个翻转,但是有一个头文件#include <algorithm>可不要忘记了哦
int main()
{string s("abcdef");string::iterator it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;reverse(s.begin(), s.end());it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;}

 ✨【sort】函数

  • 再来说一个【sort】,也很明了,就是对区间内的元素去做一个排序的操作,此时我们可以看到两个重载形式,第一个就是正常传入区间迭代器,而第二个重载形式则是可以传递【仿函数】,它也是STL的六大组件之一,我们在后续也会进行学习,这里先提一句。

  • 立马,我们来看看如何去进行使用,也是传递【begin】和【end】即可
sort(s.begin(), s.end());
  • 通过运行结果我们可以看到再 通过sort进行排序后原本的乱串变成了有序串
int main()
{string s("acdfbe");cout << "原型字符串:";string::iterator it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;reverse(s.begin(), s.end());cout << "反转字符串:";it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;sort(s.begin(), s.end());cout << "排序字符串:";it = s.begin();while (it != s.end()){cout << *it << " ";it++;}cout << endl;}

五、共勉 

      以下就是我对【C++ STL】string类-----迭代器的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++STL库的理解,请持续关注我哦!!!    

这篇关于【C++ STL】string类-----迭代器(什么是迭代器?迭代器分哪几类?迭代器的接口如何使用?)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/398837

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名