STL(模板库)
STL = Standard Template Library,标准模板库,惠普实验室开发的一系列软件的统称。STL内建在编译系统之内,加入相应头文件即可使用相关功能。STL可分为容器(containers)、迭代器(iterators)、空间配置器(allocator)、配接器(adapters)、算法(algorithms)、仿函数(functors)六个部分。(以上摘自百度百科)
STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模版函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文件:
<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack>和<utility>。
algorithm算法
STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以你所指定的规则对序列进行稳定性排序等等。这样一来,只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。
算法部分主要由头文件<algorithm>
,<numeric>
和<functional>
组成。
<algorithm>
是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
<numeric>
体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
<functional>
中则定义了一些模板类,用以声明函数对象。
STL中算法大致分为四类:
1)、非可变序列算法:指不直接修改其所操作的容器内容的算法。
2)、可变序列算法:指可以修改它们所操作的容器内容的算法。
3)、排序算法:包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
4)、数值算法:对容器内容进行数值计算。
container容器
在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。
经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码都十分相似,只是为了适应不同数据的变化而在细节上有所出入。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> |
iterator迭代器
迭代器从作用上来说是最基本的部分,可是理解起来比前两者都要费力一些(至少笔者是这样)。软件设计有一个基本原则,所有的问题都可以通过引进一个间接层来简化,这种简化在STL中就是用迭代器来完成的。
概括来说,迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。
迭代器部分主要由头文件<utility>
,<iterator>
和<memory>
组成。
<utility>
是一个很小的头文件,它包括了贯穿使用在STL中的几个模板的声明,
<iterator>
中提供了迭代器使用的许多方法,而对于的描述则十分的困难,它以不同寻常的方式为容器中的元素分配存储空间,同时也为某些算法执行期间产生的临时对象提供机制,中的主要部分是模板类allocator,它负责产生所有容器中的默认分配器。
[http://www.cnblogs.com/shiyangxt/archive/2008/09/11/1289493.html]
[http://www.cnblogs.com/biyeymyhjob/archive/2012/07/22/2603525.html]
string
不要忘记头文件<#include<string>
>
#include<iostream>
#include<string>
using namespace std;
void main()
{
string str1 = "hello";//定义和初始化
string str2 = ("world");
string str3("my heart will always go on");
string str4(str3, 6);//从str3[6]开始到结束
string str5(str3, 6, 3);//从str3[6]开始3个字符
char str[] = "popcorn";
string str6(str3, 4);//前4个,直接从char转换是这样的
string str7(10, 1);
//输出iiiiiiiiii,前面数字是个数,重复遍数,后面单字符多会截断
str7.~string();//销毁字符
//运算
string str8 = str1 + str2;//字符串拼接
str8.push_back('.');//在最后加上字符
cout << str8 << endl;
str8.append("@163");//连接字符串
str8.assign("yiyayiyayou");//重新赋值
str8.insert(4, "###");//在第四位后加入内容
cout << str8[1] << endl;//字符串的取值
cout << str8.at(3) << endl;//相当于str8[3]
string str9;
getline(cin, str9);//输入字符串
//输入字符串,以!结尾,是指输入!之后程序才接收字符完成。
cout << str9 << endl;
string str10("hello!");
str10.pop_back();
cout << str10 << endl;//删除最后一个字节
string::iterator iter = str10.begin();
//迭代器,string.begin()指向字符串首地址,string.end()指向末位地址
for (;iter != str10.end();iter++)
cout << *iter << endl;
}
vector
[http://blog.csdn.net/hancunai0017/article/details/7032383]
#include<iostream>
#include<vector>
using namespace std;
void main()
{
vector<int> vec;//声明一个数组
vec = { 1,2,1,2,3,1,3 };
for (int i = 0;i < vec.size();i++)
cout << vec[i] << endl;
}
1.push_back 在数组的最后添加一个数据
2.pop_back 去掉数组的最后一个数据
3.at 得到编号位置的数据
4.begin 得到数组头的指针
5.end 得到数组的最后一个单元+1的指针
6.front 得到数组头的引用
7.back 得到数组的最后一个单元的引用
8.max_size 得到vector最大可以是多大
9.capacity 当前vector分配的大小
10.size 当前使用数据的大小
11.resize 改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
12.reserve 改变当前vecotr所分配空间的大小
13.erase 删除指针指向的数据项
14.clear 清空当前的vector
15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)
16.rend 将vector反转构的结束指针返回(其实就是原来的begin-1)
17.empty 判断vector是否为空
18.swap 与另一个vector交换数据
定义c是一个数组
c.clear() 移除容器中所有数据。
c.empty() 判断容器是否为空。
c.erase(pos) 删除pos位置的数据
c.erase(beg,end) 删除[beg,end)区间的数据
c.front() 传回第一个数据。
c.insert(pos,elem) 在pos位置插入一个elem拷贝
c.pop_back() 删除最后一个数据。
c.push_back(elem) 在尾部加入一个数据。
c.resize(num) 重新设置该容器的大小
c.size() 回容器中实际数据的个数。
c.begin() 返回指向容器第一个元素的迭代器
c.end() 返回指向容器最后一个元素的迭代器