STL模板整理

STL

set

set模版类的定义在头文件中。

定义set对象的示例代码如下:

set<int> s;
set<double> ss;

set的基本操作:



s.begin()       //  返回指向第一个元素的迭代器
s.clear()       //  清除所有元素
s.count()       //  返回某个值元素的个数
s.empty()       //  如果集合为空,返回true(真)
s.end()         //  返回指向最后一个元素之后的迭代器,不是最后一个元素
s.equal_range() //  返回集合中与给定值相等的上下限的两个迭代器
s.erase()       //  删除集合中的元素
s.find()        //  返回一个指向被查找到元素的迭代器
s.get_allocator()   //  返回集合的分配器
s.insert()      //  在集合中插入元素
s.lower_bound() //  返回指向大于(或等于)某值的第一个元素的迭代器
s.key_comp()    //  返回一个用于元素间值比较的函数
s.max_size()    //  返回集合能容纳的元素的最大限值
s.rbegin()      //  返回指向集合中最后一个元素的反向迭代器
s.rend()        //  返回指向集合中第一个元素的反向迭代器
s.size()        //  集合中元素的数目
s.swap()        //  交换两个集合变量
s.upper_bound() //  返回大于某个值元素的迭代器
s.value_comp()  //  返回一个用于比较元素间的值的函数

multiset

在头文件中,还定义了另一个非常实用的模版类multiset(多重集合)。多重集合与集合的区别在于集合中不能存在相同元素,而多重集合中可以存在。

定义multiset对象的示例代码如下:

multiset<int> s;
multiset<double> ss;

multiset和set的基本操作相似,需要注意的是,集合的count()能返回0(无)或者1(有),而多重集合是有多少个返回多少个。

vector

在STL的头文件中定义了vector(向量容器模版类),vector容器以连续数组的方式存储元素序列,可以将vector看作是以顺序结构实现的线性表。当我们在程序中需要使用动态数组时,vector将会是理想的选择,vector可以在使用过程中动态地增长存储空间。
vector模版类需要两个模版参数,第一个参数是存储元素的数据类型,第二个参数是存储分配器的类型,其中第二个参数是可选的,如果不给出第二个参数,将使用默认的分配器。

下面给出几个常用的定义vector向量对象的方法示例:

vector<int> s;      
//  定义一个空的vector对象,存储的是int类型的元素
vector<int> s(n);   
//  定义一个含有n个int元素的vector对象
vector<int> s(first, last); 
//  定义一个vector对象,并从由迭代器first和last定义的序列[first, last)中复制初值

vector的基本操作:

s[i]                //  直接以下标方式访问容器中的元素
s.front()           //  返回首元素
s.back()            //  返回尾元素
s.push_back(x)      //  向表尾插入元素x
s.size()            //  返回表长
s.empty()           //  表为空时,返回真,否则返回假
s.pop_back()        //  删除表尾元素
s.begin()           //  返回指向首元素的随机存取迭代器
s.end()             //  返回指向尾元素的下一个位置的随机存取迭代器
s.insert(it, val)   //  向迭代器it指向的元素前插入新元素val
s.insert(it, n, val)//  向迭代器it指向的元素前插入n个新元素val
s.insert(it, first, last)   
//  将由迭代器first和last所指定的序列[first, last)插入到迭代器it指向的元素前面
s.erase(it)         //  删除由迭代器it所指向的元素
s.erase(first, last)//  删除由迭代器first和last所指定的序列[first, last)
s.reserve(n)        //  预分配缓冲空间,使存储空间至少可容纳n个元素
s.resize(n)         //  改变序列长度,超出的元素将会全部被删除,如果序列需要扩展(原空间小于n),元素默认值将填满扩展出的空间
s.resize(n, val)    //  改变序列长度,超出的元素将会全部被删除,如果序列需要扩展(原空间小于n),val将填满扩展出的空间
s.clear()           //  删除容器中的所有元素
s.swap(v)           //  将s与另一个vector对象进行交换
s.assign(first, last)
//  将序列替换成由迭代器first和last所指定的序列[first, last),[first, last)不能是原序列中的一部分

//  要注意的是,resize操作和clear操作都是对表的有效元素进行的操作,但并不一定会改变缓冲空间的大小
//  另外,vector还有其他的一些操作,如反转、取反等,不再一一列举
//  vector上还定义了序列之间的比较操作运算符(>、<、>=、<=、==、!=),可以按照字典序比较两个序列。
//  还是来看一些示例代码吧……

/*
 * 输入个数不定的一组整数,再将这组整数按倒序输出
 */

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> L;
    int x;
    while(cin >> x)
    {
        L.push_back(x);
    }
    for (int i = L.size() - 1; i >= 0; i--)
    {
        cout << L[i] << " ";
    }
    cout << endl;
    return 0;
}

queue

queue模版类的定义在头文件中。
queue与stack相似,queue模版类也需要两个模版参数,一个元素类型,一个容器类型,元素类型时必须的,容器类型时可选的,默认为deque类型。

定义queue对象的示例代码必须如下:

queue<int> q;
queue<double> qq;
q.push(x);  //  入队列
q.pop();    //  出队列
q.front();  //  访问队首元素
q.back();   //  访问队尾元素
q.empty();  //  判断队列是否为空
q.size();   //  访问队列中的元素个数

priority_queue

在头文件中,还定义了另一个非常有用的模版类priority_queue(优先队列)。优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权出队列(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。

priority_queue模版类有三个模版参数,第一个是元素类型,第二个是容器类型,第三个是比较算子。其中后两者都可以忽略,默认容器为vector,默认算子为less,即小的往前排,大的往后排(出队列时列尾元素先出队)。
定义priority_queue对象的代码示例:

priority_queue<int> q;
priority_queue<pair<int, int> > qq; //注意在两个尖括号之间一定要留空格,防止误判
priority_queue<int, vector<int>, greater<int> > qqq;//定义小的先出队列

q.empty()     //  如果队列为空,则返回true,否则返回false
q.size()      //  返回队列中元素的个数
q.pop()       //  删除队首元素,但不返回其值
q.top()       //  返回具有最高优先级的元素值,但不删除该元素
q.push(item)  //  在基于优先级的适当位置插入新元素

map

在STL的头文件中中定义了模版类map和multimap,用有序二叉树表存储类型为pair<const Key, T>的元素对序列。序列中的元素以const Key部分作为标识,map中所有元素的Key值必须是唯一的,multimap则允许有重复的Key值。

可以将map看作是由Key标识元素的元素集合,这类容器也被称为“关联容器”,可以通过一个Key值来快速决定一个元素,因此非常适合于需要按照Key值查找元素的容器。
map模版类需要四个模版参数,第一个是键值类型,第二个是元素类型,第三个是比较算子,第四个是分配器类型。其中键值类型和元素类型是必要的。

定义map对象的代码示例:

map<string, int> m;

/*  向map中插入元素  */
m[key] = value; //  [key]操作是map很有特色的操作,如果在map中存在键值为key的元素对, 则返回该元素对的值域部分,否则将会创建一个键值为key的元素对,值域为默认值。所以可以用该操作向map中插入元素对或修改已经存在的元素对的值域部分。
m.insert(make_pair(key, value));    //  也可以直接调用insert方法插入元素对,insert操作会返回一个pair,当map中没有与key相匹配的键值时,其first是指向插入元素对的迭代器,其second为true;若map中已经存在与key相等的键值时,其first是指向该元素对的迭代器,second为false。

/*  查找元素  */
int i = m[key]; //  要注意的是,当与该键值相匹配的元素对不存在时,会创建键值为key(当另一个元素是整形时,m[key]=0)的元素对。
map<string, int>::iterator it = m.find(key);    //  如果map中存在与key相匹配的键值时,find操作将返回指向该元素对的迭代器,否则,返回的迭代器等于map的end()(参见vector中提到的begin()和end()操作)。

/*  删除元素  */
m.erase(key);   //  删除与指定key键值相匹配的元素对,并返回被删除的元素的个数。
m.erase(it);    //  删除由迭代器it所指定的元素对,并返回指向下一个元素对的迭代器。

/*  其他操作  */
m.size();       //  返回元素个数
m.empty();      //  判断是否为空
m.clear();      //  清空所有元素

bitset

在 STLSTL 的头文件中 中定义了模版类 bitsetbitset,用来方便地管理一系列的 bitbit 位的类。 bitsetbitset 除了可以访问指定下标的 bitbit 位以外,还可以把它们作为一个整数来进行某些统计。

bitsetbitset 模板类需要一个模版参数,用来明确指定含有多少位。

定义 bitsetbitset 对象的示例代码:

const int MAXN = 32;

bitset<MAXN> bt;            //  bt 包括 MAXN 位,下标 0 ~ MAXN - 1,默认初始化为 0
bitset<MAXN> bt1(0xf);      //  0xf 表示十六进制数 f,对应二进制 1111,将 bt1 低 4 位初始化为 1
bitset<MAXN> bt2(012);      //  012 表示八进制数 12,对应二进制 1010,即将 bt2 低 4 位初始化为 1010
bitset<MAXN> bt3("1010");   //  将 bt3 低 4 位初始化为 1010
bitset<MAXN> bt4(s, pos, n);//  将 01 字符串 s 的 pos 位开始的 n 位初始化 bt4

bt.any()        //  bt 中是否存在置为 1 的二进制位?
bt.none()       //  bt 中不存在置为 1 的二进制位吗?
bt.count()      //  bt 中置为 1 的二进制位的个数
bt.size()       //  bt 中二进制位的个数
bt[pos]         //  访问 bt 中在 pos 处的二进制位
bt.test(pos)    //  bt 中在 pos 处的二进制位是否为 1
bt.set()        //  把 bt 中所有二进制位都置为 1
bt.set(pos)     //  把 bt 中在 pos 处的二进制位置为 1
bt.reset()      //  把 bt 中所有二进制位都置为 0
bt.reset(pos)   //  把 bt 中在pos处的二进制位置为0
bt.flip()       //  把 bt 中所有二进制位逐位取反
bt.flip(pos)    //  把 bt 中在 pos 处的二进制位取反
bt[pos].flip()  //  同上
bt.to_ulong()   //  用 bt 中同样的二进制位返回一个 unsigned long 值
os << bt        //  把 bt 中的位集输出到 os 流
上一篇:STL容器总结


下一篇:【STL源码阅读】std::sort()