【C++】:STL迭代器使用详解,很好很详细

2020年01月20日 阅读数:172
这篇文章主要向大家介绍【C++】:STL迭代器使用详解,很好很详细,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

写在前面,迭代器这种东西,就是为了使访问简单!!ios

容器::iterator iter;程序员

for(iter= 容器.begin();iter!=容器.end();iter++){算法

cout<<*iter或者是 iter->first等等之类的                                    //迭代器就是这么个套路数组

}数据结构


而后就是set,set就是一个集合,仅此而已,而其余的,像是map比较有意思,提供了两种数据结构的对应,而其余的咱们不要简单的认为是队列和栈,咱们要认为这是一种容器,可以包含多种数据结构,用了这种思想,咱们就会想的更明白dom


下面给出摘抄下来的正文:函数



指针与数组
指针与其它数据结构呢?好比说链表?
存储空间是非连续的。不能经过对指向这种数据结构的指针作累加来遍历。
能不能提供一个行为相似指针的类,来对非数组的数据结构进行遍历呢?这样咱们就可以以一样的方式来遍历全部数据结构(容器)。
迭代器(Iterator)是指针(pointer)的泛化,它容许程序员以相同的方式处理不一样的数据结构(容器)。STL中有五种类型的迭代器,它们分别知足必定的要求。不一样的迭代器要求定义的操做不同。

箭头表示左边的迭代器必定知足右边迭代器须要的条件。spa

下面的图表画出了这几种:指针

input output
\/
forward
|
bidirectional
|
random accesscode

要注意,上面这图表并非代表它们之间的继承关系:而只是描述了迭代器的种类和接口。处于图表下层的迭代器都是相对于处于图表上层迭代器的扩张集。例如:forward迭代器不但拥有input和output迭代器的全部功能,还拥有更多的功能。

好比某个算法须要一个双向迭代器(Bidirctional Iterator),你能够把一个任意存取迭代器(Random Access Iterator)做为参数;但反之不行。

迭代器iterator 提供了一种通常化的方法对顺序或关联容器类型中的每一个元素进行连续访问
例如,假设iter为任意容器类型的一个iterator,则++iter 表示向前移动迭代器使其指向容器的下一个元素,而*iter 返回iterator 指向元素的值,每种容器类型都提供一个begin()和一个end()成员函数。
begin()返回一个iterator 它指向容器的第一个元素
end()返回一个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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector>
 
int main()
{
     std::vector< char > charVector;
 
     int x;
     for (x=0; x<10; ++x)
         charVector.push_back(65 + x);
 
     int size = charVector.size();
     for (x=0; x<size; ++x)
     {
         std::vector< char >::iterator start =
             charVector.begin();
         charVector.erase(start);
         std::vector< char >::iterator iter;
         for (iter = charVector.begin();
                 iter != charVector.end(); iter++)
         {
             std::cout << *iter;
         }
         std::cout << std::endl;
     }
 
     return 0;
}

二、deque

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <deque>
 
int main()
{
     std::deque< char > charDeque;
     int x;
     for (x=0; x<10; ++x)
         charDeque.push_front(65 + x);
 
     int size = charDeque.size();
     for (x=0; x<size; ++x)
     {
         std::deque< char >::iterator start =
             charDeque.begin();
         charDeque.erase(start);
         std::deque< char >::iterator iter;
         for (iter = charDeque.begin();
                 iter != charDeque.end(); iter++)
         {
             std::cout << *iter;
         }
         std::cout << std::endl;
     }
 
     return 0;
}

三、list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <list>
 
int main()
{
     // Create and populate the list.
     int x;
     std::list< char > charList;
     for (x=0; x<10; ++x)
         charList.push_front(65 + x);
 
     // Display contents of list.
     std::cout << "Original list: " ;
     std::list< char >::iterator iter;
     for (iter = charList.begin();
             iter != charList.end(); iter++)
     {
         std::cout << *iter;
         //char ch = *iter;
         //std::cout << ch;
     }
     std::cout << std::endl;
     
     // Insert five Xs into the list.
     std::list< char >::iterator start = charList.begin();
     charList.insert(++start, 5, 'X' );
 
     // Display the result.
     std::cout << "Resultant list: " ;
     for (iter = charList.begin();
     iter != charList.end(); iter++)
     {
         std::cout << *iter;
         //char ch = *iter;
         //std::cout << ch;
     }
     
     return 0;
}

四、set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <set>
 
int main()
{
     // Create the set object.
     std::set< char > charSet;
 
     // Populate the set with values.
     charSet.insert( 'E' );
     charSet.insert( 'D' );
     charSet.insert( 'C' );
     charSet.insert( 'B' );
     charSet.insert( 'A' );
 
     // Display the contents of the set.
     std::cout << "Contents of set: " << std::endl;
     std::set< char >::iterator iter;
     for (iter = charSet.begin(); iter != charSet.end(); iter++)
         std::cout << *iter << std::endl;
     std::cout << std::endl;
 
     // Find the D.
     iter = charSet.find( 'D' );
     if (iter == charSet.end())
         std::cout << "Element not found." ;
     else
         std::cout << "Element found: " << *iter;
 
     return 0;
}

五、multiset

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <set>
 
int main()
{
     // Create the first set object.
     std::multiset< char > charMultiset1;
 
     // Populate the multiset with values.
     charMultiset1.insert( 'E' );
     charMultiset1.insert( 'D' );
     charMultiset1.insert( 'C' );
     charMultiset1.insert( 'B' );
     charMultiset1.insert( 'A' );
     charMultiset1.insert( 'B' );
     charMultiset1.insert( 'D' );
 
     // Display the contents of the first multiset.
     std::cout << "Contents of first multiset: " << std::endl;
     std::multiset< char >::iterator iter;
     for (iter = charMultiset1.begin();
             iter != charMultiset1.end(); iter++)
         std::cout << *iter << std::endl;
     std::cout << std::endl;
 
     // Create the second multiset object.
     std::multiset< char > charMultiset2;
 
     // Populate the multiset with values.
     charMultiset2.insert( 'J' );
     charMultiset2.insert( 'I' );
     charMultiset2.insert( 'H' );
     charMultiset2.insert( 'G' );
     charMultiset2.insert( 'F' );
     charMultiset2.insert( 'G' );
     charMultiset2.insert( 'I' );
     
     // Display the contents of the second multiset.
     std::cout << "Contents of second multiset: "
         << std::endl;
     for (iter = charMultiset2.begin();
     iter != charMultiset2.end(); iter++)
         std::cout << *iter << std::endl;
     std::cout << std::endl;
     
     // Compare the sets.
     if (charMultiset1 == charMultiset2)
         std::cout << "set1 == set2" ;
     else if (charMultiset1 < charMultiset2)
         std::cout << "set1 < set2" ;
     else if (charMultiset1 > charMultiset2)
         std::cout << "set1 > set2" ;
     
     return 0;
}

六、map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <map>
 
typedef std::map< int , char > MYMAP;
 
int main()
{
     // Create the first map object.
     MYMAP charMap1;
 
     // Populate the first map with values.
     charMap1[1] = 'A' ;
     charMap1[4] = 'D' ;
     charMap1[2] = 'B' ;
     charMap1[5] = 'E' ;
     charMap1[3] = 'C' ;
 
     // Display the contents of the first map.
     std::cout << "Contents of first map: " << std::endl;
     MYMAP::iterator iter;
     for (iter = charMap1.begin();
             iter != charMap1.end(); iter++)
     {
         std::cout << (*iter).first << " --> " ;
         std::cout << (*iter).second << std::endl;
     }
     std::cout << std::endl;
 
     // Create the second map object.
     MYMAP charMap2;
 
     // Populate the first map with values.
     charMap2[1] = 'F' ;
     charMap2[4] = 'I' ;
     charMap2[2] = 'G' ;
     charMap2[5] = 'J' ;
     charMap2[3] = 'H' ;
 
     // Display the contents of the second map.
     std::cout << "Contents of second map: " << std::endl;
     for (iter = charMap2.begin();
             iter != charMap2.end(); iter++)
     {
         std::cout << (*iter).first << " --> " ;
         std::cout << (*iter).second << std::endl;
     }
     std::cout << std::endl;
 
     // Compare the maps.
     if (charMap1 == charMap2)
         std::cout << "map1 == map2" ;
     else if (charMap1 < charMap2)
         std::cout << "map1 < map2" ;
     else if (charMap1 > charMap2)
         std::cout << "map1 > map2" ;
     
     return 0;
}

七、multimap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <map>
 
typedef std::multimap< int , char > MYMAP;
 
int main()
{
     // Create the first multimap object.
     MYMAP charMultimap;
 
     // Populate the multimap with values.
     charMultimap.insert(MYMAP::value_type(1, 'A' ));
     charMultimap.insert(MYMAP::value_type(4, 'C' ));
     charMultimap.insert(MYMAP::value_type(2, 'B' ));
     charMultimap.insert(MYMAP::value_type(7, 'E' ));
     charMultimap.insert(MYMAP::value_type(5, 'D' ));
     charMultimap.insert(MYMAP::value_type(3, 'B' ));
     charMultimap.insert(MYMAP::value_type(6, 'D' ));
 
     // Display the contents of the first multimap.
     std::cout << "Contents of first multimap: " << std::endl;
     MYMAP::iterator iter;
     for (iter = charMultimap.begin();
             iter != charMultimap.end(); iter++)
     {
         std::cout << (*iter).first << " --> " ;
         std::cout << (*iter).second << std::endl;
     }
     std::cout << std::endl;
 
     // Create the second multimap object.
     MYMAP charMultimap2;
 
     // Populate the second multimap with values.
     charMultimap2.insert(MYMAP::value_type(1, 'C' ));
     charMultimap2.insert(MYMAP::value_type(4, 'F' ));
     charMultimap2.insert(MYMAP::value_type(2, 'D' ));
     charMultimap2.insert(MYMAP::value_type(7, 'E' ));
     charMultimap2.insert(MYMAP::value_type(5, 'F' ));
     charMultimap2.insert(MYMAP::value_type(3, 'E' ));
     charMultimap2.insert(MYMAP::value_type(6, 'G' ));
 
     // Display the contents of the second multimap.
     std::cout << "Contents of second multimap: " << std::endl;
     for (iter = charMultimap2.begin();
             iter != charMultimap2.end(); iter++)
     {
         std::cout << (*iter).first << " --> " ;
         std::cout << (*iter).second << std::endl;
     }
     std::cout << std::endl;
 
     // Compare the multimaps.
     if (charMultimap == charMultimap2)
         std::cout << "multimap1 == multimap2" ;
     else if (charMultimap < charMultimap2)
         std::cout << "multimap1 < multimap2" ;
     else if (charMultimap > charMultimap2)
         std::cout << "multimap1 > multimap2" ;
     
     return 0;
}

八、stack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <list>
#include <stack>
 
int main()
{
     std::stack< int , std::list< int > > intStack;
 
     int x;
     std::cout << "Values pushed onto stack:"
               << std::endl;
     for (x=1; x<11; ++x)
     {
         intStack.push(x*100);
         std::cout << x*100 << std::endl;
     }
 
     std::cout << "Values popped from stack:"
               << std::endl;
     int size = intStack.size();
     for (x=0; x<size; ++x)
     {
         std::cout << intStack.top() << std::endl;
         intStack.pop();
     }
 
     return 0;
}

九、queue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <list>
#include <queue>
 
int main()
{
     std::queue< int , std::list< int > > intQueue;
 
     int x;
     std::cout << "Values pushed onto queue:"
               << std::endl;
     for (x=1; x<11; ++x)
     {
         intQueue.push(x*100);
         std::cout << x*100 << std::endl;
     }
 
     std::cout << "Values removed from queue:"
               << std::endl;
     int size = intQueue.size();
     for (x=0; x<size; ++x)
     {
         std::cout << intQueue.front() << std::endl;
         intQueue.pop();
     }
 
     return 0;
}

十、priority_queue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <list>
#include <queue>
 
int main()
{
     std::priority_queue< int , std::vector< int >,std::greater< int > > intPQueue;