更多关于STL文章——STL学习笔记
容器适配器
queue
Class queue<> 实现出一个 queue (也称为FIFO[先进先出])。你可以使用 push() 将任意数量的元素放入 queue 中,也可以使用 pop() 将元素依其插入次序从容器中移除(此即所谓“先进先出[FIFO]”)。换句话说,queue 是一个典型的数据缓冲构造。
class queue 定义如下:
namespace std{
template <typename T, typename Container = deque<T>>
class queue;
}
第一个 template 参数代表元素类型。带有默认值的第二个 template 参数定义 queue 内部存放元素的实际容器,默认为 deque。
queue 只是很单纯地把各项操作转化为内部容器的对应调用。你可以使用任何 sequence 容器支持 queue,只要它们支持:front()、back()、push_back() 和 pop_back()等操作。
只能访问 queue<T> 容器适配器的第一个和最后一个元素。只能在容器的末尾添加新元素,只能从头部移除元素。
template<typename Tp, typename Sequence = deque<Tp> >
class queue
{
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
typedef typename Sequence::size_type size_type;
typedef Sequence container_type;
}
类型名称 | 定义 |
---|---|
value_type | 元素的类型 |
reference | 用以指向元素之reference类型 |
const_reference | 用以指向只读元素之reference类型 |
size_type | 不带正负号的整数类型,用来表现大小 |
container_type | 内部容器的类型 |
构造:
explicit queue (const container_type& ctnr);
//构造一个容器适配器,其内部容器被初始化为ctnr的副本。
explicit queue (container_type&& ctnr = container_type());
//构造一个容器适配器,其内部容器通过移动构造来获取ctnr的值。
template<class Alloc> explicit queue (const Alloc& alloc);
//用分配器构造函数初始化,构造一个容器适配器,其内部容器使用alloc作为参数构造。
template<class Alloc> queue (const container_type& ctnr, const Alloc& alloc);
//构造一个容器适配器,其内部容器使用cntr和alloc作为参数构造。
template<class Alloc> queue (container_type&& ctnr, const Alloc& alloc);
//使用分配器构造函数进行移动初始化,构造一个容器适配器,其内部容器使用std::move(cntr)和alloc作为参数构造。
template<class Alloc> queue (const queue& x, const Alloc& alloc);
//构造一个容器适配器,其内部容器使用x的内部容器(复制),分配器为alloc
template<class Alloc> queue (queue&& x, const Alloc& alloc);移动+分配器
//构造一个容器适配器,其内部容器使用x的内部容器(移动),分配器为alloc
小例子:
#include<iostream>
#include<queue>
#include<list>
#include<deque>
using namespace std;
int main()
{
deque<int> mydeck (3,100); //创建一个deque含3个100
list<int> mylist (2,200); //创建一个list含2个200
queue<int> first; //创建一个空的队列
queue<int> second (mydeck); //用mydeck的拷贝作为队列的初始值
//第二个参数模板默认即为 deque,因此可以不写。
queue<int,list<int>> third; //空队列,列表作为底层容器
queue<int,list<int>> fourth (mylist); //用mylist的拷贝作为队列的初始值
cout << "size of first: " << first.size() << endl;
cout << "size of second: " << second.size() << endl;
cout << "size of third: " << third.size() << endl;
cout << "size of fourth: " << fourth.size() << endl;
return 0;
}
size of first: 0
size of second: 3
size of third: 0
size of fourth: 2
下面为其成员函数:
- empty
判断容器是否为空
bool empty() const;
- size
返回容器大小
size_type size() const;
- front
返回队列第一个元素的引用
reference& front();
const_reference& front() const;
- back
返回队列最后一个元素的引用
reference& back();
const_reference& back() const;
- push
将一个元素添加到队列中
void push (const value_type& val);
void push (value_type&& val);
- emplace
用传给 emplace() 的参数调用 T 的构造函数,在 queue 的尾部生成对象
template <class… Args> void emplace (Args&&… args);
- pop
删除队列第一个元素
void pop();
- swap
交换两个容器
void swap (queue& x);
没有迭代器。访问元素的唯一方式是遍历容器内容,并移除访问过的每一个元素。如:
#include<iostream>
#include<queue>
#include<deque>
using namespace std;
int main()
{
deque<int> myDeque ({1,3,5,7,9,11,13,15,17,19});
queue<int> myQueue(myDeque);
while(!myQueue.empty())
{
cout<<myQueue.front()<<" ";
myQueue.pop();
}
cout<<endl;
return 0; //输出1 3 5 7 9 11 13 15 17 19
}
图片来源:c语言中文网
示例
来自 hdu1312
题目描述
有一个长方形的房间,铺着方形瓷砖,瓷砖为红色或黑色。一个人站在黑色瓷砖上,他可以按上、下、左、右方向移动到相邻的瓷砖。但他不能在红色瓷砖上移动,只能在黑色瓷砖上移动。编程计算他可以到达的黑色瓷砖的数量。
输入:
第1行包含两个正整数W和H,W和H分别表示x方向和y方向上的瓷砖数量。W和H均不超过20。下面有H行,每行包含W个字符。每个字符表示一片瓷砖的颜色。用符号表示如下:“ . ”表示黑色瓷砖;“ # ”表示红色瓷砖;“ @ ”代表黑色瓷砖上的人,在数据集中只出现一次。
6 9
…#.
…#
…
…
…
…
…
#@…#
.#…#.
11 9
.#…
.#.#######.
.#.#…#.
.#.#.###.#.
.#.#…@#.#.
.#.#####.#.
.#…#.
.#########.
…
11 6
…#…#…#…
…#…#…#…
…#…#…###
…#…#…#@.
…#…#…#…
…#…#…#…
7 7
…#.#…
…#.#…
###.###
…@…
###.###
…#.#…
…#.#…
0 0
输出:
一个数字,这个人从初始瓷砖能到达的瓷砖总数量(包括起点)。
45
59
6
13
#include<iostream>
#include<queue>
using namespace std;
static char room[23][23];
static int dir[4][2] = {
{-1,0}, //向左
{0,-1},//向上
{1,0},//向右
{0,1}//向下
};
static int Wx,Hy,num;//Wx行,Hy列,用num统计可走的位置有多少
#define CHECK(x,y) (x<Wx && x>=0 && y>=0 && y<Hy)//判断是否在room中
struct node {int x,y;};
void BFS(int dx,int dy)
{
num=1; //起点也包含在砖块内
queue<node> q; //队列中放坐标点
node start,next;
start.x = dx;
start.y = dy;
q.push(start);
while(!q.empty()){
start = q.front();
q.pop();
for(int i=0;i<4;++i){//按左、上、右、下 4个方向顺时针逐一搜索
next.x = start.x + dir[i][0];
next.y = start.y + dir[i][1];
if(CHECK(next.x,next.y) && room[next.x][next.y] == '.'){
room[next.x][next.y] = '#'; //进队之后标记为已经处理过
num++;
q.push(next);
}
}
}
}
int main()
{
int x,y,dx(0),dy(0);
while(cin>>Wx>>Hy){ //Wx行,Hy列
if(Wx==0 && Hy==0) //结束
break;
for(y=0;y<Hy;++y){//有Hy列
for(x=0;x<Wx;++x){ //一次读入一行
cin>>room[x][y];
if(room[x][y] == '@'){ //读入起点
dx = x;
dy = y;
}
}
}
num = 0;
BFS(dx,dy);
cout<<num<<endl;
}
return 0;
}
常用于BFS搜索 可见图的基本算法(BFS和DFS)