一、迭代器(Iterator)

背景:指针可以用来遍历存储空间连续的数据结构,但是对于存储空间费连续的,就需要寻找一个行为类似指针的类,来对非数组的数据结构进行遍历。

定义:迭代器是一种检查容器内元素并遍历元素的数据类型。

迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。

迭代器(Iterator)是指针(pointer)的泛化,它允许程序员用相同的方式处理不同的数据结构(容器)。

(1)迭代器类似于C语言里面的指针类型,它提供了对对象的间接访问。

(2)指针是C语言中的知识点,迭代器是C++中的知识点。指针较灵活,迭代器功能较丰富。

(3)迭代器提供一个对容器对象或者string对象的访问方法,并定义了容器范围。

迭代器和指针的区别:

容器和string有迭代器类型同时拥有返回迭代器的成员。如:容器有成员begin和end,其中begin成员复制返回指向第一个元素的迭代器,而end成员返回指向容器尾元素的下一个位置的迭代器,也就是说end指示的是第一个不合法地址,所以end返回的是尾后迭代器。

容器迭代器的使用

每种容器类型都定义了自己的迭代器类型,如vector:vector< int>:: iterator iter;//定义一个名为iter的变量,数据类型是由vector< int>定义的iterator 类型。简单说就是容器类定义了自己的iterator类型,用于访问容器内的元素。每个容器定义了一种名为iterator的类型,这种类型支持迭代器的各种行为。

我么们先讲一下各种迭代器的类型,在讲容器所用的迭代器类型,就可以明白怎么操作。

常见迭代器类型如下:

|--|--|

所有迭代器| 操作

p++ | 后置自增迭代器

++p | 前置自增迭代器

输入迭代器|操作介绍

*p| 复引用迭代器,作为右值

p=p1 | 将一个迭代器赋给另一个迭代器(迭代器指向地址值)

p==p1| 比较迭代器的相等性(比较地址)

p!=p1 |比较迭代器的不等性

输出迭代器|操作

*p|复引用迭代器,作为左值

|p=p1|将一个迭代器赋给另一个迭代器|

|正向迭代器| 提供输入输出迭代器的所有功能|

|双向迭代器|操作|

|--p|前置自减迭代器

|p--|后置自减迭代器

|随机迭代器| |

|p+=i| 将迭代器递增i位|

|p-=i|将迭代器递减i位|

|p+i|在p位加i位后的迭代器|

p-i|在p位减i位后的迭代器|

p[i]|返回p位元素偏离i位的元素引用|

p<p1|如果迭代器p的位置在p1前,返回true,否则返回false|

p<=p1|p的位置在p1的前面或同一位置时返回true,否则返回false|

p>p1|如果迭代器p的位置在p1后,返回true,否则返回false|

p>=p1|p的位置在p1的后面或同一位置时返回true,否则返回false|

只有顺序容器和关联容器支持迭代器遍历,各容器支持的迭代器的类别如下:

容器 支持的迭代器类别 说明
vector 随机访问 一种随机访问的数组类型,提供了对数组元素进行快速随机访问以及在序列尾部进行快速的插入和删除操作的功能。可以再需要的时候修改其自身的大小
deque 随机访问 一种随机访问的数组类型,提供了序列两端快速进行插入和删除操作的功能。可以再需要的时候修改其自身的大小
list 双向 一种不支持随机访问的数组类型,插入和删除所花费的时间是固定的,与位置无关。
set 双向 一种随机存取的容器,其关键字和数据元素是同一个值。所有元素都必须具有惟一值。
multiset 双向 一种随机存取的容器,其关键字和数据元素是同一个值。可以包含重复的元素。
map 双向 一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个特定的关键字只能与一个元素关联。
multimap 双向 一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个关键字可以与多个数据元素关联。
stack 不支持 适配器容器类型,用vector,deque或list对象创建了一个先进后出容器
queue 不支持 适配器容器类型,用deque或list对象创建了一个先进先出容器
priority_queue 不支持 适配器容器类型,用vector或deque对象创建了一个排序队列

二、容器

所有容器都支持自定义数据类型,就是结构体。

(一) vector

使用此容器需在程序前加上头文件#include< vector >。

vector可理解为变长数组,基于倍增思想。当以已申请vector长度为m时,若实际长度n=m,则申请长度为2m的数组,将内容转移至新地址上,并释放旧空间;删除元素时,若n<=m/4,则释放一半空间。

vector容器能像数组一样随机访问第i个数a[i],但不支持随机插入.

#include<vector>       //头文件
vector<int> a; 定义了一个int类型的vector容器a
vector<int> b[100];定义了一个int类型的vector容器b组
struct rec{···};
vector<rec> c; /定义了一个rec类型的vector容器c
vector<int>::iterator it; //vector的迭代器,与指针类似

具体操作如下:

 a.size()            //返回实际长度(元素个数),O(1)复杂度
a.empty() //容器为空返回1,否则返回0,O(1)复杂度
a.clear() //把vector清空
a.begin() //返回指向第一个元素的迭代器,*a.begin()与a[0]作用相同
a.end() //越界访问,指向vector尾部,指向第n个元素再往后的边界
a.front() //返回第一个元素的值,等价于*a.begin和a[0]
a.back() //返回最后一个元素的值,等价于*--a.end()和a[size()-1]
a.push_back(x) //把元素x插入vector尾部
a.pop_back() //删除vector中最后一个元素

迭代器使用与指针类似,可如下遍历整个容器

for ( vector<int>::iterator it=a.begin() ; it!=a.end() ; it++ )

queue

循环队列queue需使用头文件< queue >

queue<int> q;   //定义了一个int类型的队列容器q
struct rec{···};queue<rec> q; //定义了一个rec类型的队列容器q
q.push(x); //从队尾使元素x入队,O(1)
q.pop(x); //使队首元素出队,O(1)
int x=q.front(); //询问队首元素的值,O(1)
int y=q.back(); //询问队尾元素的值,O(1)

priority_queue

优先队列priority_queue可理解为一个大根二叉堆,必须定义“小于号”,而int,string本身就能比较。同样需要头文件< queue >。

其定义方式与queue相似。

priority_queue<int> q;  由大到小
priority_queue<pair<int,int>> q; //pair是一个数对,由first和scond两个元素构成,按照第一个排序
priority_queue<int, vector<int>, greater<int> >qi2; //由小到大,小根堆,vector<int>是适配器,不用知道很详细,记住就行
struct rec //举个栗子
{
int a,b,c;
bool operator<(const rec&w)
{
if(a==w.a) return b==w.b?c<w.c:b<w.b;
return a<w.a;
}
};
priority_queue<rec> q; 如果不写重载函数,会出错,他不知道怎么排序
q.push(x); //插入 O(log n)
q.pop(); //删除堆顶元素 O(log n)
q.top(); //查询堆顶元素 O(1)

可通过插入元素的相反数取出时再取反,或重载“小于号”的方式实现小根堆,通过懒惰删除法实现随机删除操作。

deque

双端队列,是一个支持在两端高效插入或删除元素的连续线性存储空间,可像数组一样随机访问,使用前加头文件< deque >。

q.begin()/q.end()              //头/尾迭代器,与vector类似
q.front()/q.back() //头/尾元素,与queue类似
q.push_back(x)/q.push_front(x) //从队尾/队头入队
q.pop_back(x)/q.pop_front(x) //从队尾/队头出队
q.clear() //清空队列

定义方式

deque<类型> 名称

ps:clear复杂度为O(n),其余为O(1)。

set/multiset

两容器相似,但set为有序集合,元素不能重复,multiset为有序多重集合,可包含若干相等的元素,内部通过红黑树实现,支持的函数基本相同,同样必须定义“小于号”运算符,头文件为< set >。

其迭代器不支持随机访问,支持星号(*)结束引用,仅支持 ++ 、-- 两个与算术有关的操作。迭代器it++,则指向从小到大排序的结果中排在it下一名的元素,两操作时间复杂度均为O(log n)。

q.size()  //返回容器内元素个数
q.empty() //判断容器是否为空
q.clear() //清空容器
q.begin()/q.end() //作用与上文几种容器类似
q.insert(x) //将元素x插入集合中,O(log n)
q.find(x) //查找等于x的元素,返回其迭代器,无则返回q.end(),O(log n)
q.lower_bound(x) //查找>=x的元素中最小的一个,返回指向该元素的迭代器
q.upper_bound(x) //查找>x的元素中最小的一个,返回指向该元素的迭代器
q.erase(it) //删除迭代器it指向的元素,O(log n)
q.erase(x) //删除所有等于x的元素,复杂度为O(k+log n),k为被删除的元素个数
q.count(x) //返回等于x的元素个数,O(k+log n),k为元素x的个数

定义方式

set<int> demo 定义一个类型为int的set容器
struct rec
{
int a,b,c;
bool operator<(const rec&w)
{
if(a==w.a) return b==w.b?c<w.c:b<w.b;
return a<w.a;
}
};
set<rec> ob; 一样所有排序的容器不重载就出错

map/multimap

map/multimap映射容器的元素数据是由一个Key和一个Value成的,key与映照value之间具有一一映照的关系。

map/multimap容器的数据结构也采用红黑树来实现的,map插入元素的键值不允许重复,类似multiset,multimap的key可以重复。比较函数只对元素的key进行比较,元素的各项数据只能通过key检索出来。虽然map与set采用的都是红黑树的结构,但跟set的区别主要是set的一个键值和一个映射数据相等,Key=Value。

map<first,second> a;
//map,会按照first(键值)排序(查找也是);

map/multimap用法

头文件

#include< map >

map成员函数

begin()				 //返回指向 map 头部的迭代器
clear() // 删除所有元素
count() //返回指定元素出现的次数
empty() // 如果 map 为空则返回 true
end() //返回指向 map 末尾的迭代器
erase() // 删除一个元素
find() // 查找一个元素
insert() //插入元素
key_comp() //返回比较元素 key 的函数
lower_bound() //返回键值>=给定元素的第一个位置
max_size() //返回可以容纳的最大元素个数
rbegin() //返回一个指向 map 尾部的逆向迭代器
rend() //返回一个指向 map 头部的逆向迭代器
size() //返回 map 中元素的个数
swap() //交换两个 map

创建map对象

#include<iostream>
#include<map>
using namespace std;
map<int,char>mp;//定义map容器

创建结构体map对象

struct student{
int birth;
string name;
};
int id;
typedef map<int,student> Student;// 这里相当于给map<int,student> 起了个别名Student,后续代码均可以用student代替map<int,student> 使用。

插入结构体对象

接上文代码

Stduent  a;
cin>>id>>student.birth>>student.name;
a.insert(make_pair(id,student));

栈(stack)

1.定义:

栈是一种只能在某一端插入和删除数据的特殊线性表。他按照先进先出的原则存储数据,先进的数据被压入栈底,最后进入的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后被压入栈的,最先弹出)。因此栈也称先进后出表。

允许进行插入删除操作的一端称为栈顶,另一端称为栈底。栈底固定,栈顶浮动。插入元素称为进栈,删除一个元素称为进栈,栈内元素为零称为空栈。

2.stack成员函数

bool empty ( ) ————>栈为空返回true,否则返回false;
void pop ( ) ————>删除栈顶元素,出栈;
void push(const TYPE&value)————> 插入新元素value,放置在栈顶进栈;TYPE:类型int,char…;
size_type size ( ) ————> 返回堆栈中元素个数;(注意注意!!!!切不可赋值给int ,很容易超过int的范围
TYPE&top()————> 查看当前栈顶元素;

List

定义:List类表示可通过索引访问的对象的强类型列表,提供用于对列表进行搜索、排序和操作的方法。

作用:

泛型最常见的用途是泛型集合

我们在创建列表类时,列表项的数据类型可能是int,string或其它类型,如果对列表类的处理方法相同,

就没有必要事先指定数据类型,留待列表类实例化时再指定。相当于把数据类型当成参数,这样可以最

大限度地重用代码,保护类型的安全以及提高性能。

定义 list<类型> 名称

成员函数

l.begin()	将迭代器返回到开头(Return iterator to beginning)
l.end() 将迭代器返回到最后(Return iterator to end)
l.rbegin() Return reverse iterator to reverse beginning
l.rend() Return reverse iterator to reverse end
l.l.empty() 检查容器是否为空
l.size() 返回当前容器内元素个数
l.max_size() 返回当前容器能容纳的最大元素数量
l.front() 访问第一个元素
l.back() 访问最后一个元素
l.push_front() 将元素插入到开头
l.pop_front() 删除第一个元素
l.push_back() 将元素插入到最后
l.pop_back() 删除最后一个元素
l.insert() 插入元素
l.erase() 删除元素
l.swap() 交换两个 list 内容
l.resize ()改变容器大小
l.clear() 删除容器所有内容

bitset

bitset可看作一个多位二进制数,每8位占用1个字节,相当于采用了状态压缩的二进制数组,并支持基本的位运算。一般以32位整数的运算次数为基准估算运行时间,n位bitset执行一次的位运算复杂度可视为n/32,效率较高。头文件< bitset >。

同样具有~,&,|,^,<<,>>操作符,==,!=可比较二进制数是否相等

bitset<10000> q;      //声明一个10000位的二进制数
q[k] //表示q的第k位,可取值,赋值,最低位为q[0]
q.count() //返回有多少位1
q.none() //所有位都为0则返回true,至少1位为1则返回false
q.any() //所有位都为0则返回false,至少1位为1则返回true,与函数none相反
q.set() //把所有位变为1
q.set(k,v) //把第k位变为v,即q[k]=v
q.reset() //把所有位变为0
q.reset(k) //把第k位变为0,即q[k]=0
q.flip() //把所有位取反,即s=~s
q.flip(k) //把第k位取反,即q[k]^=1

疯子的算法总结(三) STL Ⅱ迭代器(iterator) + 容器的更多相关文章

  1. STL迭代器iterator

    一:迭代器原理 迭代器是一个“可遍历STL容器内全部或部分元素”的对象. 迭代器指出容器中的一个特定位置. 迭代器就如同一个指针. 迭代器提供对一个容器中的对象的访问方法,并且可以定义了容器中对象的范 ...

  2. 【C++】:STL迭代器使用---[容器::iterator iter;]

    参考文章:http://blog.csdn.net/qq_23100787/article/details/51388163 迭代器这种东西,就是为了使访问简单!! 容器::iterator iter ...

  3. STL 迭代器 iterator const

    STL迭代器很多时候可以当成指针来使用. 但是指针一般可以用const来控制访问. 那迭代器呢. #include <iostream> #include <vector> u ...

  4. [C++STL] 迭代器 iterator 的使用

    定义 迭代器是一种检查容器内元素并遍历元素的数据类型,表现的像指针. 基本声明方式 容器::iterator it = v.begin();//例:vector<int>::iterato ...

  5. STL理论基础、容器、迭代器、算法

    一.STL基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段 ...

  6. 疯子的算法总结(二) STL Ⅰ 算法 ( algorithm )

    写在前面: 为了能够使后续的代码具有高效简洁的特点,在这里讲一下STL,就不用自己写堆,写队列,但是做为ACMer不用学的很全面,我认为够用就好,我只写我用的比较多的. 什么是STL(STl内容): ...

  7. stl中的容器、迭代器和算法----vector中的find实现

    来源 http://blog.csdn.net/huangyimin/article/details/6133650 stl包括容器.迭代器和算法: 容器 用于管理一些相关的数据类型.每种容器都有它的 ...

  8. C++之STL迭代器(iterator)

    [摘要]本文是对STL--迭代器(iterator)的讲解,对学习C++编程技术有所帮助,与大家分享. 原文:http://www.cnblogs.com/qunews/p/3761405.html ...

  9. stl变易算法(三)

    本篇接着前面stl变易算法(一)和stl变易算法(二)继续讲述变易算法. 这里将介绍完余下的变易算法,主要有:填充fill.n次填充fill_n.随机生成元素generate.随机生成n个元素gene ...

随机推荐

  1. ASP.NET Core on K8S学习初探(3)部署API到K8S

    在上一篇<基本概念快速一览>中,我们把基本的一些概念快速地简单地不求甚解地过了一下,本篇开始我们会将ASP.NET Core WebAPI部署到K8S,从而结束初探的旅程. Section ...

  2. Python向FTP服务器上传文件

    上传 代码示例: #!/usr/bin/python # -*- coding:utf-8 -*- from ftplib import FTP ftp = FTP() # 打开调试级别2, 显示详细 ...

  3. C# 获取计算机相关信息

    整理了一个关于计算机相关系统的资料 需要引入命名空间: 1. 在'解决方案资源管理器' 窗口中->右击项目-> '添加' -> '引用' 弹出引用管理器 2. 在引用处理器中,程序集 ...

  4. spring的context:exclude-filter 与 context:include-filter

    1 在主容器中(applicationContext.xml),将Controller的注解打消掉 <context:component-scan base-package="com& ...

  5. WebGL2系列之多采样渲染缓冲对象

    在很久很久以前,盘古开辟了天地,他的头顶着天,脚踩着地,最后他挂了.他的毛发变成了森林,他的血液变成了河流,他的肌肉变成了大地......卡! 哦,不对,在很久很久以前,你属于我,我拥有你.你还有没有 ...

  6. Java SpringBoot 如何使用 IdentityServer4 作为验证学习笔记

    这边记录下如何使用IdentityServer4 作为 Java SpringBoot 的 认证服务器和令牌颁发服务器.本人也是新手,所以理解不足的地方请多多指教.另外由于真的很久没有写中文了,用词不 ...

  7. Excel催化剂开源第5波-任务窗格在OFFICE2013中新建文档不能同步显示问题解决

    在OFFICE2013及之后,使用了单文档界面技术,不同于以往版本可以共享任务空格.功能区.所以当开发任务窗格时,需要考虑到每一个工作薄都关联一个任务窗格. 背景介绍 单文档界面摘录官方定义如下:对 ...

  8. [小米OJ] 2. 找出单独出现的数字

    解法一: map 1.45 ms #include <algorithm> #include <bitset> #include <cmath> #include ...

  9. C/C++用new、delete分配回收堆中空间

    int *CreateList() 10 { 11 int a[5]; 12 int *a = new int[5]; 13 delete[] a; 14 15 int a(5); 16 int a ...

  10. mysql查看视图用户

    select `DEFINER` from  information_schema.VIEWS;