C++ STL详解

转载自:http://www.cnblogs.com/shiyangxt/archive/2008/09/11/1289493.html

一、STL简介

STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来

的。现在虽说它主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间。

STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类

组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、

<memory>、<numeric>、<queue>、<set>、<stack>和<utility>

二、算法

大家都能取得的一个共识是函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说,一个求方根的函数,在使用浮点数作为其参数类型的情况下的可重用性肯定比

使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择,直到真正想使用模板或者说对模板进行特化的时候,STL就利用了这一点提供了相当多的有用

算法。它是在一个有效的框架中完成这些算法的——你可以将所有的类型划分为少数的几类,然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。

STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以你所指定的规则对序列进行稳定性排序等等。这样一来

,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。

算法部分主要由头文件<algorithm>,<numeric>和<functional>组成。

<algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。

 

<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。

 

<functional>中则定义了一些模板类,用以声明函数对象。

三、容器

在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。

经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码都十分相似,只是为了适应不同数据的变化而在细节上有所出入。STL容器

就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构,通过设置一些模版类,STL容器对最常用的数据结构提供了支持,这些模板的参数

允许我们指定容器中元素的数据类型,可以将我们许多重复而乏味的工作简化。

容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack>和<queue>组成。对于常用的一些容器和容器适配器(可以看作由其它容器实现的容器),可以通过下表总结一下它们和相应头文件的对应关系。

向量(vector) 连续存储的元素<vector>

列表(list)       由节点组成的双向链表,每个结点包含着一个元素<list>

双队列(deque) 连续存储的指向不同元素的指针所组成的数组<deque>

集合(set) 由节点组成的红黑树,每个节点都包含着一个元素,节点之间以某种作用于元素对的谓词排列,没有两个不同的元素能够拥有相同的次序 <set>

多重集合(multiset) 允许存在两个次序相等的元素的集合 <set>

栈(stack) 后进先出的值的排列 <stack>

队列(queue) 先进先出的执的排列 <queue>

优先队列(priority_queue) 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列 <queue>

映射(map) 由{键,值}对组成的集合,以某种作用于键对上的谓词排列 <map>

多重映射(multimap) 允许键对有相等的次序的映射 <map>

四、迭代器

下面要说的迭代器从作用上来说是最基本的部分,可是理解起来比前两者都要费力一些(至少笔者是这样)。软件设计有一个基本原则,所有的问题都可以通过引进一个间接层来

简化,这种简化在STL中就是用迭代器来完成的

概括来说,迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。

迭代器部分主要由头文件<utility>,<iterator>和<memory>组成。

<utility>是一个很小的头文件,它包括了贯穿使用在STL中的几个模板的声明,

<iterator>中提供了迭代器使用的许多方法,而对于<memory>的描述则十分的困难,它以不同寻常的方式为容器中的元素分配存储空间,同时也为某些算法执行期间产生的临时对象提供机制,<memory>中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器

----------------------------------------------------分割线---------------------------------------------------------------

以下转自:http://www.cnblogs.com/duoduo369/archive/2012/04/12/2439118.html

学完c++快一年了,感觉很有遗憾,因为一直没有感觉到c++的强大之处,当时最大的感觉就是这个东西的输入输出比C语言要简单好写。

  后来我发现了qt,opencv,opengl,原来,c++好玩的狠。

  在这些图形库之外,最常用的可能就是STL,这个东西由于当时学c++的时候迷迷糊糊,完全是一头雾水,上学期数据结构之后开始有点儿开窍了,现在把才c++STL中常用的函数,用法贴一下,也是记录一下,希望能给一样迷糊的盆友们一些帮助。

  整理自《ACM程序设计》  

  迭代器(iterator)

  个人理解就是把所有和迭代有关的东西给抽象出来的,不管是数组的下标,指针,for里面的、list里面的、vector里面的,抽象一下变成了iterator

 1 #include <iostream>
2 #include <vector>
3
4 using namespace std;
5
6 int main()
7 {
8 vector<int> v;
9 for(int i = 0; i < 10; ++i )
10 {
11 v.push_back(i);
12 }
13 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
14 {
15 cout << *it << " ";
16 }
17 cout << endl;
18 return 0;
19 }

  

  求和(<numeric> accumulate)

  accumulate(v.begin(),v.end(),0),把从 v.begin() 开始到 v.end()结束所有的元素加到 0上面去

#include <iostream>
#include <vector>
#include <numeric> using namespace std; int main()
{
vector<int> v;
for(int i = 0; i < 10; ++i )
{
v.push_back(i);
}
for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
cout << accumulate(v.begin(),v.end(),0) << endl;
return 0;
}

  vector(动态数组)

  vector有内存管理的机制,也就是说对于插入和删除,vector可以动态调整所占用的内存空间。  

  vector相关函数

#include <iostream>
#include <vector> using namespace std; int main()
{
vector<int> v;
v.push_back(3); //数组尾部插入3
v.push_back(2);
v.push_back(1);
v.push_back(0);
cout << " 下标 " << v[3] << endl;
cout << " 迭代器 " << endl;
for(vector<int>::iterator i = v.begin();i!= v.end();++i)
{
cout << *i << " ";
}
cout << endl;
//在第一个元素之前插入111 insert begin+n是在第n个元素之前插入
v.insert(v.begin(),111);
//在最后一个元素之后插入222 insert end + n 是在n个元素之后插入
v.insert(v.end(),222); for(vector<int>::iterator i = v.begin();i!= v.end();++i)
{
cout << *i << " ";
}
cout << endl; vector<int> arr(10);
for(int i = 0; i < 10; i++)
{
arr[i] = i;
}
for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
{
cout << *i << " ";
}
cout << endl; //删除 同insert
arr.erase(arr.begin()); for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
{
cout << *i << " " ;
}
cout << endl ; arr.erase(arr.begin(),arr.begin()+5); for(vector<int>::iterator i = arr.begin();i!= arr.end();++i)
{
cout << *i << " " ;
}
cout << endl ;
return 0 ;
}

  数组转置 (<algorithm> reverse)

  reverse(v.begin(),v.end())

 1 #include<iostream>
2 #include<vector>
3 #include<algorithm>
4
5 using namespace std;
6
7 int main()
8 {
9 vector<int> v;
10 for(int i = 0; i < 10; ++i)
11 {
12 v.push_back(i);
13 }
14 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
15 {
16 cout << *it << " ";
17 }
18 cout << endl;
19
20 reverse(v.begin(),v.end());
21
22
23 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
24 {
25 cout << *it << " ";
26 }
27 cout << endl;
28 return 0;
29 }

  排序(<algorithm> sort)

  sort(v.begin(),v.end())

 1 #include<iostream>
2 #include<vector>
3 #include<algorithm>
4
5 using namespace std;
6
7 bool Comp(const int &a,const int &b)
8 {
9 return a>b;
10 }
11
12 int main()
13 {
14 vector<int> v;
15 v.push_back(1);
16 v.push_back(3);
17 v.push_back(2);
18 v.push_back(55);
19 v.push_back(-1);
20 v.push_back(0);
21 v.push_back(2);
22 v.push_back(3);
23 v.push_back(4);
24
25 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
26 {
27 cout << *it << " ";
28 }
29 cout << endl;
30
31 //默认升序
32 sort(v.begin(),v.end());
33
34
35 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
36 {
37 cout << *it << " ";
38 }
39 cout << endl;
40
41 //用降序 需要自定义一个降序函数
42 sort(v.begin(),v.end(),Comp);
43
44
45 for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
46 {
47 cout << *it << " ";
48 }
49 cout << endl;
50
51 return 0;
52 }

  字符串(<string>)

  输入

 1 #include<iostream>
2 #include<string>
3 #include<cstdio>
4
5 using namespace std;
6
7 int main()
8 {
9 string s1;
10 s1 = "hello";
11
12 string s2;
13 char s[1024];
14 //scanf 输入速度比cin快的多
15 //scanf 是C函数,不可以输入string
16 scanf("%s",s);
17 s2 = s;
18
19 cout << s1 << endl;
20 cout << s2 << endl;
21
22 return 0;
23 }

 

  尾部添加字符字符串直接用+号 例如: s += 'a'; s += "abc",或者使用append方法,s.append(“123”)

  删除 (erase clear)

  s.erase(it + 1,it + 4); clear()

 1 #include<iostream>
2 #include<string>
3
4 using namespace std;
5
6 int main()
7 {
8 string s;
9 s = "0123456789";
10 cout << s << endl;
11
12 string::iterator it = s.begin();
13
14 //删除s[3]
15 s.erase(it+3);
16 cout << s << endl;
17
18 //删除s[1]~s[3]
19 s = "0123456789";
20 s.erase(it + 1,it + 4);
21 cout << s << endl;
22
23 //全部删除
24 s.clear();
25 cout << "clear : " << s << endl;
26
27 return 0;
28 }

  查找(find)

  用find找到string里面第一个要找到元素(char或者串),找到返回数组下标,找不到返回end()迭代器

  string和vector有很多相同的东西,比如length(),size(),empty(),reverse(),相对也容易,就不一一说了。

  数字化处理(string)

  经常会遇到这样一种情况,有一个数字,需要把每一位给提取出来,如果用取余数的方法,花费的时间就会很长,所以可以当成字符串来处理,方便、省时。

  例子:求一个整数各位数的和

 1 #include<iostream>
2 #include<string>
3
4 using namespace std;
5
6 int main()
7 {
8 string s;
9 s = "123456789";
10 int sum = 0;
11 for(int i = 0; i < s.size(); ++i)
12 {
13 switch(s[i])
14 {
15 case '1': sum += 1;break;
16 case '2': sum += 2;break;
17 case '3': sum += 3;break;
18 case '4': sum += 4;break;
19 case '5': sum += 5;break;
20 case '6': sum += 6;break;
21 case '7': sum += 7;break;
22 case '8': sum += 8;break;
23 case '9': sum += 9;break;
24 }
25 }
26
27 cout << sum << endl;
28
29 return 0;
30 }

  string与char *

  

 1 #include<iostream>
2 #include<string>
3 #include<cstdio>
4
5 using namespace std;
6
7 int main()
8 {
9 string s_string;
10 char s_char[1000];
11 scanf("%s",s_char);
12
13 s_string = s_char;
14
15 //printf输出char* 时用c_str处理
16 printf(s_string.c_str());
17 cout << endl;
18
19 printf("%s",s_char);
20 cout << endl;
21
22 cout << s_char << endl;
23 cout << s_string << endl;
24 return 0;
25 }

  sscanf

  

 1 #include<iostream>
2 #include<string>
3 #include<cstdio>
4
5 using namespace std;
6
7 int main()
8 {
9 string s1,s2,s3;
10 char sa[100],sb[100],sc[100];
11 sscanf("abc 123 wcd","%s%s%s",sa,sb,sc);
12 s1 = sa;
13 s2 = sb;
14 s3 = sc;
15 cout << s1 << " " << s2 << " " << s3 << endl;
16
17 //将字符串分离成数字,分隔符为',''$'
18 int a,b,c;
19 sscanf("4,5$6","%d,%d$%d",&a,&b,&c);
20 cout << a << " " << b << " " << c << endl;
21 return 0;
22 }

  string与数值相互转换( sprintf <sstream> )

 1 #include<iostream>
2 #include<string>
3 #include<sstream>
4 #include<cstdio>
5
6 using namespace std;
7
8 //c++ 方法 把数转换为string
9 string converToString(double x)
10 {
11 ostringstream o;
12 if( o << x)
13 {
14 // str()没有'\0' c_str有
15 return o.str();
16 }
17 return "error";
18 }
19
20 double converFromString(const string &s)
21 {
22 istringstream i(s);
23 double x;
24 if( i >> x)
25 {
26 return x;
27 }
28 //if error
29 return 0.0;
30 }
31 int main()
32 {
33 char b[100];
34 string s1;
35
36 //c语言方法
37 sprintf(b,"%d",1987);
38 s1 = b;
39 cout << s1 << endl;
40
41 string s2 = converToString(1954);
42 cout << s2 << endl;
43
44 string s3 = "202";
45 int c = converFromString(s3);
46 cout << c << endl;
47
48 string s4 = "casacsa6";
49 int d = converFromString(s4);
50 cout << d << endl;
51
52 string s5 = "21abf4";
53 int f = converFromString(s5);
54 cout << f << endl;
55
56 return 0;
57 }

  set容器

  set是用红黑树的平衡二叉索引树的数据结构来实现的,插入时,它会自动调节二叉树排列,把元素放到适合的位置,确保每个子树根节点的键值大于左子树所有的值、小于右子树所有的值,插入重复数据时会忽略。set迭代器采用中序遍历,检索效率高于vector、deque、list,并且会将元素按照升序的序列遍历。set容器中的数值,一经更改,set会根据新值旋转二叉树,以保证平衡,构建set就是为了快速检索(python中的set一旦建立就是一个常量,不能改的)。

  multiset,与set不同之处就是它允许有重复的键值。

  正反遍历,迭代器iterator、reverse_iterator

#include<iostream>
#include<set> using namespace std; int main()
{
set<int> v;
v.insert(1);
v.insert(3);
v.insert(5);
v.insert(2);
v.insert(4);
v.insert(3); //中序遍历 升序遍历
for(set<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl; for(set<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
{
cout << *rit << " ";
}
cout << endl; return 0;
}

  自定义比较函数,insert的时候,set会使用默认的比较函数(升序),很多情况下需要自己编写比较函数。

  1、如果元素不是结构体,可以编写比较函数,下面这个例子是用降序排列的(和上例插入数据相同):

 1 #include<iostream>
2 #include<set>
3
4 using namespace std;
5
6 struct Comp
7 {
8 //重载()
9 bool operator()(const int &a, const int &b)
10 {
11 return a > b;
12 }
13 };
14 int main()
15 {
16 set<int,Comp> v;
17 v.insert(1);
18 v.insert(3);
19 v.insert(5);
20 v.insert(2);
21 v.insert(4);
22 v.insert(3);
23
24 for(set<int,Comp>::iterator it = v.begin(); it != v.end(); ++it)
25 {
26 cout << *it << " ";
27 }
28 cout << endl;
29
30 for(set<int,Comp>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
31 {
32 cout << *rit << " ";
33 }
34 cout << endl;
35
36 return 0;
37 }

  2、元素本身就是结构体,直接把比较函数写在结构体内部,下面的例子依然降序:

 1 #include<iostream>
2 #include<set>
3 #include<string>
4
5 using namespace std;
6
7 struct Info
8 {
9 string name;
10 double score;
11
12 //重载 <
13 bool operator < (const Info &a) const
14 {
15 return a.score < score;
16 }
17 };
18 int main()
19 {
20 set<Info> s;
21 Info info;
22
23 info.name = "abc";
24 info.score = 123.3;
25 s.insert(info);
26
27 info.name = "EDF";
28 info.score = -23.53;
29 s.insert(info);
30
31
32 info.name = "xyz";
33 info.score = 73.3;
34 s.insert(info);
35
36 for(set<Info>::iterator it = s.begin(); it != s.end(); ++it)
37 {
38 cout << (*it).name << ":" << (*it).score << endl;
39 }
40 cout << endl;
41
42 for(set<Info>::reverse_iterator rit = s.rbegin(); rit != s.rend(); ++rit)
43 {
44 cout << (*rit).name << ":" << (*rit).score << endl;
45 }
46 cout << endl;
47
48 return 0;
49 }

  multiset与set的不同之处就是key可以重复,以及erase(key)的时候会删除multiset里面所有的key并且返回删除的个数。

  map

  map也是使用红黑树,他是一个键值对(key:value映射),便利时依然默认按照key程序的方式遍历,同set。

 1 #include<iostream>
2 #include<map>
3 #include<string>
4
5 using namespace std;
6
7 int main()
8 {
9 map<string,double> m;
10
11 //声明即插入
12 m["li"] = 123.4;
13 m["wang"] = 23.1;
14 m["zhang"] = -21.9;
15 m["abc"] = 12.1;
16 for(map<string,double>::iterator it = m.begin(); it != m.end(); ++it)
17 {
18 //first --> key second --> value
19 cout << (*it).first << ":" << (*it).second << endl;
20 }
21 cout << endl;
22 return 0;
23 }

  用map实现数字分离

  string --> number

  之前用string进行过数字分离,现在使用map

 1 #include<iostream>
2 #include<map>
3 #include<string>
4
5 using namespace std;
6
7 int main()
8 {
9 map<char,int> m;
10
11 m['0'] = 0;
12 m['1'] = 1;
13 m['2'] = 2;
14 m['3'] = 3;
15 m['4'] = 4;
16 m['5'] = 5;
17 m['6'] = 6;
18 m['7'] = 7;
19 m['8'] = 8;
20 m['9'] = 9;
21 /*
22 等价于
23 for(int i = 0; i < 10; ++i)
24 {
25 m['0' + i] = i;
26 }
27 */
28
29 string sa;
30 sa = "9876543210";
31 int sum = 0;
32 for( int i = 0; i < sa.length(); ++i)
33 {
34 sum += m[sa[i]];
35 }
36 cout << sum << endl;
37 return 0;
38 }

  number --> string

 1 #include <iostream>
2 #include <map>
3 #include <string>
4
5 using namespace std;
6
7 int main()
8 {
9 map<int,char> m;
10
11 for(int i = 0; i < 10; ++i)
12 {
13 m[i] = '0' + i;
14 }
15
16 int n = 7;
17
18 string out = "the number is :";
19 cout << out + m[n] << endl;
20
21 return 0;
22 }

  multimap

  multimap由于允许有重复的元素,所以元素插入、删除、查找都与map不同。

  插入insert(pair<a,b>(value1,value2))

 1 #include <iostream>
2 #include <map>
3 #include <string>
4
5 using namespace std;
6
7 int main()
8 {
9 multimap<string,double> m;
10
11 m.insert(pair<string,double>("Abc",123.2));
12 m.insert(pair<string,double>("Abc",123.2));
13 m.insert(pair<string,double>("xyz",-43.2));
14 m.insert(pair<string,double>("dew",43.2));
15
16 for(multimap<string,double>::iterator it = m.begin(); it != m.end(); ++it )
17 {
18 cout << (*it).first << ":" << (*it).second << endl;
19 }
20 cout << endl;
21
22 return 0;
23 }

  至于删除和查找,erase(key)会删除掉所有key的map,查找find(key)返回第一个key的迭代器

  deque

  deque和vector一样,采用线性表,与vector唯一不同的是,deque采用的分块的线性存储结构,每块大小一般为512字节,称为一个deque块,所有的deque块使用一个Map块进行管理,每个map数据项记录各个deque块的首地址,这样以来,deque块在头部和尾部都可已插入和删除元素,而不需要移动其它元素。使用push_back()方法在尾部插入元素,使用push_front()方法在首部插入元素,使用insert()方法在中间插入元素。一般来说,当考虑容器元素的内存分配策略和操作的性能时,deque相对vectore更有优势。(下面这个图,我感觉Map块就是一个list< map<deque名字,deque地址> >)

  插入删除

  遍历当然可以使用下标遍历,在这里使用迭代器。

 1 #include <iostream>
2 #include <deque>
3
4 using namespace std;
5
6 int main()
7 {
8 deque<int> d;
9
10 //尾部插入
11 d.push_back(1);
12 d.push_back(3);
13 d.push_back(2);
14 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
15 {
16 cout << (*it) << " ";
17 }
18 cout << endl << endl;
19
20 //头部插入
21 d.push_front(10);
22 d.push_front(-23);
23 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
24 {
25 cout << (*it) << " ";
26 }
27 cout << endl << endl;
28
29 d.insert(d.begin() + 2,9999);
30 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
31 {
32 cout << (*it) << " ";
33 }
34 cout << endl << endl;
35
36 //反方向遍历
37 for(deque<int>::reverse_iterator rit = d.rbegin(); rit != d.rend(); ++rit )
38 {
39 cout << (*rit) << " ";
40 }
41 cout << endl << endl;
42
43 //删除元素pop pop_front从头部删除元素 pop_back从尾部删除元素 erase中间删除 clear全删
44 d.clear();
45 d.push_back(1);
46 d.push_back(2);
47 d.push_back(3);
48 d.push_back(4);
49 d.push_back(5);
50 d.push_back(6);
51 d.push_back(7);
52 d.push_back(8);
53 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
54 {
55 cout << (*it) << " ";
56 }
57 cout << endl;
58
59 d.pop_front();
60 d.pop_front();
61 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
62 {
63 cout << (*it) << " ";
64 }
65 cout << endl;
66
67 d.pop_back();
68 d.pop_back();
69 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
70 {
71 cout << (*it) << " ";
72 }
73 cout << endl;
74
75 d.erase(d.begin() + 1);
76 for(deque<int>::iterator it = d.begin(); it != d.end(); ++it )
77 {
78 cout << (*it) << " ";
79 }
80 cout << endl;
81 return 0;
82 }

  list

  list<int> l

  插入:push_back尾部,push_front头部,insert方法前往迭代器位置处插入元素,链表自动扩张,迭代器只能使用++--操作,不能用+n -n,因为元素不是物理相连的。

  遍历:iterator和reverse_iterator正反遍历

  删除:pop_front删除链表首元素;pop_back()删除链表尾部元素;erase(迭代器)删除迭代器位置的元素,注意只能使用++--到达想删除的位置;remove(key) 删除链表中所有key的元素,clear()清空链表。

  查找:it = find(l.begin(),l.end(),key)

  排序:l.sort()

  删除连续重复元素:l.unique() 【2 8 1 1 1 5 1】 --> 【 2 8 1 5 1】

  bitset

  从来没用过,上两幅图吧就:

  stack(后进先出)

  这个印象深刻,学数据结构的时候做表达式求值的就是用的栈。

 1 #include <iostream>
2 #include <stack>
3 using namespace std;
4
5 int main()
6 {
7
8 stack<int> s;
9 s.push(1);
10 s.push(2);
11 s.push(4);
12 s.push(5);
13
14 cout << s.size() << endl;
15
16 while(s.empty() != true)
17 {
18 cout << s.top() << endl;
19 s.pop();
20 }
21 return 0;
22 }

  stack然我唯一费解之处在于,貌似它没有iterator,可以试试s.begin()编译器报错的。

  queue(先进先出)

  queue有入队push(插入)、出队pop(删除)、读取队首元素front、读取队尾元素back、empty,size这几种方法

  priority_queue(最大元素先出)

 1 #include <iostream>
2 #include <queue>
3 using namespace std;
4
5 int main()
6 {
7
8 priority_queue<int> pq;
9
10 pq.push(1);
11 pq.push(3);
12 pq.push(2);
13 pq.push(8);
14 pq.push(9);
15 pq.push(0);
16
17 cout << "size: " << pq.size() << endl;
18
19 while(pq.empty() != true)
20 {
21 cout << pq.top() << endl;
22 pq.pop();
23 }
24 return 0;
25 }

  重载操作符同set重载操作符。

C++ STL详解的更多相关文章

  1. STL详解

    STL概貌                                                                                                ...

  2. c++ 关于二分的STL 详解

    一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函 ...

  3. 《STL详解》解题报告

    看完发现文档缺页...... 3.5  菲波那契数 vector<int> v; v.push_back(); v.push_back(); ;i < ;++i) v.push_ba ...

  4. 《STL详解》读书笔记

    vector 向量容器v.insert(v.begin(), num);//增加v.erase(v.begin(), v.end()); //擦除v.erase(v.begin());reverse( ...

  5. stl——vector详解

    stl——vector详解 stl——vector是应用最广泛的一种容器,类似于array,都将数据存储于连续空间中,支持随机访问.相对于array,vector对空间应用十分方便.高效,迭代器使ve ...

  6. 2.3 C++STL vector容器详解

    文章目录 2.3.1 引入 2.3.2 代码实例 2.3.3 运行结果 总结 2.3.1 引入 vector 容器 动态数组 可变数组 vector容器 单口容器(尾部操作效率高) vector动态增 ...

  7. STL bind1st bind2nd详解

    STL bind1st bind2nd详解   先不要被吓到,其实这两个配接器很简单.首先,他们都在头文件<functional>中定义.其次,bind就是绑定的意思,而1st就代表fir ...

  8. 跟我一起学STL(2)——vector容器详解

    一.引言 在上一个专题中,我们介绍了STL中的六大组件,其中容器组件是大多数人经常使用的,因为STL容器是把运用最广的数据结构实现出来,所以我们写应用程序时运用的比较多.然而容器又可以序列式容器和关联 ...

  9. STL之heap与优先级队列Priority Queue详解

    一.heap heap并不属于STL容器组件,它分为 max heap 和min heap,在缺省情况下,max-heap是优先队列(priority queue)的底层实现机制.而这个实现机制中的m ...

随机推荐

  1. 「小程序JAVA实战」小程序模块页面引用(18)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-18/ 上一节,讲了模板的概念,其实小程序还提供了模块的概念.源码:https://github.c ...

  2. docker redis4.0 集群(cluster)搭建

    前言 redis集群对于很多人来说非常熟悉,在前些日子,我也有一位大兄弟也发布过一篇关于在阿里云(centOS7)上搭建redis 集群的文章,虽然集群搭建的文章在网上很多,我比较喜欢这篇文章的地方是 ...

  3. python实战===python控制键盘鼠标:pynput

    Python控制键盘鼠标:pynput 地址:https://pypi.python.org/pypi/pynput 这个库让你可以控制和监控输入设备. 对于每一种输入设备,它包含一个子包来控制和监控 ...

  4. Python基础:文件的基本操作

    # 打开文件(如果不存在则新建) 向其中写入 f = open('D:\\test.txt', 'w') f.write('hello world, i am here!') f.close() pr ...

  5. VUE+WebPack游戏设计:'乘法防线'游戏设计

  6. 蒟蒻LQL的博客

    这里是蒟蒻LQL的博客!!! 一枚水的不能再水的弱校ACMer···· 可能会在这写一些题解或者别的什么乱七八糟的··· 可能大概没什么人看,就当错题本好了o(* ̄▽ ̄*)ブ 因为太弱了难免有错误!发 ...

  7. 关于java是值传递还是引用传递

    一.概念 实际上对这两种传递方式,知乎上有个回答说得很好: 值传递和引用传递,属于函数调用时参数的求值策略(Evaluation Strategy),这是对调用函数时,求值和传值的方式的描述,而非传递 ...

  8. asp.net 母版页使用详解

    母版页是VS2005中新引入的一个概念,它很好地实现界面设计的模块化,并且实现实现了代码的重用.它就像婚纱影楼中的婚纱模板,同一个婚纱模板可以给不同的新人用,只要把他们的照片贴在已有的婚纱模板就可以形 ...

  9. HTTP/2协议

    一.简介 http://toutiao.com/a6258917202906104066/

  10. Android中Cursor类的概念和用法[转]

    首页 > 程序开发 > 移动开发 > Android > 正文   Android中Cursor类的概念和用法 2011-09-07      0个评论       收藏    ...