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看作是由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 流