顺序容器的插入迭代器与适配器
顺序容器的插入迭代器
-
用于向容器头部、尾部或中间指定位置插入元素的迭代器
-
包括前插迭代器(frontinserter)、后插迭代器(backinsrter)和任意位置插入迭代器(inserter)
-
例:
list<int> s; back_inserter iter(s); *(iter++) = 5; //通过iter把5插入s末尾
顺序容器的适配器
-
以顺序容器为基础构建一些常用数据结构,是对顺序容器的封装
-
栈(stack):最先压入的元素最后被弹出
-
队列(queue):最先压入的元素最先被弹出
-
优先级队列(priority_queue):最“大”的元素最先被弹出
-
栈和队列模板
-
栈模
template <class T, class Sequence = deque<T> > class stack;
- 队列模板
template <class T, class FrontInsertionSequence = deque<T> > class queue;
- 栈可以用任何一种顺序容器作为基础容器,而队列只允许用前插顺序容器(双端队列或列表)
栈和队列共同支持的操作
-
s1 op s2 op可以是==、!=、<、<=、>、>=之一,它会对两个容器适配器之间的元素按字典序进行比较
-
s.size() 返回s的元素个数
-
s.empty() 返回s是否为空
-
s.push(t) 将元素t压入到s中
-
s.pop() 将一个元素从s中弹出,对于栈来说,每次弹出的是最后被压入的元素,而对于队列,每次被弹出的是最先被压入的元素
-
不支持迭代器,因为它们不允许对任意元素进行访问
栈和队列不同的操作
-
栈的操作
-
s.top() 返回栈顶元素的引用
-
-
队列操作
-
s.front() 获得队头元素的引用
-
s.back() 获得队尾元素的引用
-
例10-7 利用栈反向输出单词
//10_7.cpp, 省略头部分
int main() {
stack<char> s;
string str;
cin >> str; //从键盘输入一个字符串
//将字符串的每个元素顺序压入栈中
for (string::iterator iter = str.begin(); iter != str.end(); ++iter)
s.push(*iter);
//将栈中的元素顺序弹出并输出
while (!s.empty()) {
cout << s.top();
s.pop();
}
cout << endl;
return 0;
}
运行结果如下:
congratulations
snoitalutargnoc
优先级队列
例10-8 细胞分裂模拟
一种细胞在诞生(即上次分裂)后会在500到2000秒内分裂为两个细胞,每个细胞又按照同样的规律继续分裂。
-
优先级队列也像栈和队列一样支持元素的压入和弹出,但元素弹出的顺序与元素的大小有关,每次弹出的总是容器中最“大”的一个元素。
template <class T, class Sequence = vector<T> > class priority_queue;
-
优先级队列的基础容器必须是支持随机访问的顺序容器。
-
支持栈和队列的size、empty、push、pop几个成员函数,用法与栈和队列相同。
-
优先级队列并不支持比较操作。
-
与栈类似,优先级队列提供一个top函数,可以获得下一个即将被弹出元素(即最“大”的元素)的引用。
// 10.8.cpp, 头部分省略
const int SPLIT_TIME_MIN = 500; //细胞分裂最短时间
const int SPLIT_TIME_MAX = 2000; //细胞分裂最长时间
class Cell;
priority_queue<Cell> cellQueue;//定义一个优先队列对象,用来存储待分裂的细胞
class Cell { //细胞类
private:
static int count; //细胞总数
int id; //当前细胞编号
int time; //细胞分裂时间
public:
Cell(int birth) : id(count++) { //birth为细胞诞生时间
//初始化,确定细胞分裂时间
time = birth + (rand() % (SPLIT_TIME_MAX - SPLIT_TIME_MIN))+ SPLIT_TIME_MIN;
}
int getId() const { return id; } //得到细胞编号
int getSplitTime() const { return time; } //得到细胞分裂时间
bool operator < (const Cell& s) const //定义“<”
{ return time > s.time; }
void split() { //细胞分裂
Cell child1(time), child2(time); //建立两个子细胞
cout << time << "s: Cell #" << id << " splits to #"
<< child1.getId() << " and #" << child2.getId() << endl;
cellQueue.push(child1); //将第一个子细胞压入优先级队列
cellQueue.push(child2); //将第二个子细胞压入优先级队列
}
};
int Cell::count = 0;//类外定义静态数据变量
int main() {
srand(static_cast<unsigned>(time(0)));//准备随机数种子
int t; //模拟时间长度
cout << "Simulation time: ";
cin >> t;
cellQueue.push(Cell(0)); //将第一个细胞压入优先级队列
while (cellQueue.top().getSplitTime() <= t) {
cellQueue.top().split(); //模拟下一个细胞的分裂
cellQueue.pop(); //将刚刚分裂的细胞弹出
}
return 0;
}
/*
运行结果如下:
Simulation time: 5000
971s: Cell #0 splits to #1 and #2
1719s: Cell #1 splits to #3 and #4
1956s: Cell #2 splits to #5 and #6
2845s: Cell #6 splits to #7 and #8
3551s: Cell #3 splits to #9 and #10
3640s: Cell #4 splits to #11 and #12
3919s: Cell #5 splits to #13 and #14
4162s: Cell #10 splits to #15 and #16
4197s: Cell #8 splits to #17 and #18
4317s: Cell #7 splits to #19 and #20
4686s: Cell #13 splits to #21 and #22
4809s: Cell #12 splits to #23 and #24
4818s: Cell #17 splits to #25 and #26
*/