全排列函数next_permutation
STL 中专门用于排列的函数(可以处理存在重复数据集的排列问题)
头文件:#include
using namespace std;
调用: next_permutation(start, end);
注意:函数要求输入的是一个升序排列的序列的头指针和尾指针.
用法:
// 数组
int a[N];
sort(a, a+N);
next_permutation(a, a+N);
// 向量
vector ivec;
sort(ivec.begin(), ivec.end());
next_permutation(ivec.begin(), ivec.end());
例子:
vector myVec;
// 初始化代码
sort(myVec.begin(),myVec.end());
do{
for (i = 0 ;i < size;i ++ ) cout << myVec[i] << " \t " ;
cout << endl;
}while (next_permutation(myVec.begin(), myVec.end()));
ACM/ICPC 竞赛之STL--pair
STL 的
例如,想要定义一个对象表示一个平面坐标点,则可以:
pair
在
在题1067--Ugly Numbers 中,就可以用pair 来表示推演树上的结点,用first 表示结点的值,用second 表示结点是由父结点乘以哪一个因子得到的。
#include
#include
using namespace std;
typedef pair node_type;
int main()
{
unsigned long result[1500];
priority_queue< node_type, vector,
greater > Q;
Q.push( make_pair(1, 2) );
for (int i=0; i<1500; i++)
{
node_type node = Q.top(); Q.pop();
switch(node.second)
{
case 2: Q.push( make_pair(node.first*2, 2) );
case 3: Q.push( make_pair(node.first*3, 3) );
case 5: Q.push( make_pair(node.first*5, 5) );
}
result[i] = node.first;
}
int n;
cin >> n;
while (n>0)
{
cout << result[n-1] << endl;
cin >> n;
}
return 0;
}
ACM/ICPC 竞赛之STL--vector
在STL 的
vector 模板类需要两个模板参数,第一个参数是存储元素的数据类型,第二个参数是存储分配器的类型,其中第二个参数是可选的,如果不给出第二个参数,将使用默认的分配器。
下面给出几个常用的定义vector 向量对象的方法示例:38
vector
定义一个空的vector 对象,存储的是int 类型的元素。
vector
vector
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, x) 向迭代器it 指向的元素前插入新元素val。
s.insert(it, n, x)向迭代器it 指向的元素前插入n 个x。
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 对象v 进行交换。
s.assign(first, last)将序列替换成由迭代器first 和last 所指定的序列[first, last)。[first, last)不能是原序列中的一部分。要注意的是,resize 操作和clear 操作都是对表的有效元素进行的操作,但并不一定会改变缓冲空间的大小。另外,vector 还有其他一些操作如反转、取反等,不再一下列举。vector 上还定义了序列之间的比较操作运算符(>, <, >=, <=, ==, !=),
可以按照字典序比较两个序列。还是来看一些示例代码。输入个数不定的一组整数,再将这组整数按倒序输出,
如下所示:
#include
#include
using namespace std;
int main()
{
vector 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;
}
ACM/ICPC 竞赛之STL--iterator 简介
iterator(迭代器)是用于访问容器中元素的指示器,从这个意义上说,iterator(迭代器)相当于数据结构中所说的“遍历指针”,也可以把iterator(迭代器)看作是一种泛化的指针。STL 中关于iterator(迭代器)的实现是相当复杂的,这里我们暂时不去详细讨论关于iterator(迭代器)的实现和使用,而只对iterator(迭代器)做一点简单的介绍。
简单地说,STL 中有以下几类iterator(迭代器):
输入iterator(迭代器),在容器的连续区间内向前移动,可以读取容器内任意值;输出iterator(迭代器),把值写进它所指向的容器中;前向iterator(迭代器),读取队列中的值,并可以向前移动到下一位置(++p,p++);双向iterator(迭代器),读取队列中的值,并可以向前向后遍历容器;随机访问iterator(迭代器), 可以直接以下标方式对容器进行访问,vector 的iterator(迭代器)就是这种iterator(迭代器);流iterator(迭代器),可以直接输出、输入流中的值;每种STL 容器都有自己的iterator(迭代器)子类,下面先来看一段简单的示例代码:
#include
#include
using namespace std;
main()
{
vector s;
for (int i=0; i<10; i++)
s.push_back(i);
for (vector::iterator it=s.begin(); it!=s.end();it++)
cout << *it << " ";
cout << endl;
return 1;
}
vector 的begin()和end()方法都会返回一个vector::iterator 对象,分别指向vector 的首元素位置和尾元素的下一个位置(我们可以称之为结束标志位置)。对一个iterator(迭代器)对象的使用与一个指针变量的使用极为相似,或者可以这样说,指针就是一个非常标准的iterator(迭代器)。再来看一段稍微特别一点的代码:
#include
#include
using namespace std;
main()
{
vector s;
s.push_back(1);
s.push_back(2);
s.push_back(3);
copy(s.begin(), s.end(), ostream_iterator(cout, ""));
cout <
这段代码中的copy 就是STL 中定义的一个模板函数,copy(s.begin(),s.end(), ostream_iterator
ACM/ICPC 竞赛之STL--string
字符串是程序中经常要表达和处理的数据,我们通常是采用字符数组或字符指针来表示字符串。STL 为我们提供了另一种使用起来更为便捷的字符串的表达方式:string。string 类的定义在头文件
#include
#include
using namespace std;
int main()
{
string s = "Hello! ", name;
cin >> name;
s += name;
s += '!';
cout << s << endl;
return 0;
}
再以题1064--Parencoding 为例,看一段用string 作为容器,实现由P
代码还原括号字符串的示例代码片段:
int m;
cin >> m; // P 编码的长度
string str; // 用来存放还原出来的括号字符串
int leftpa = 0; // 记录已出现的左括号的总数
for (int j=0; j int p; cin >> p; for (int k=0; k str += ')'; leftpa = p; } stack(栈)和queue(队列)也是在程序设计中经常会用到的数据容器,STL为我们提供了方便的stack(栈)的queue(队列)的实现。39准确地说,STL 中的stack 和queue 不同于vector、list 等容器,而是对这些容器的重新包装。这里我们不去深入讨论STL 的stack 和queue 的实现细节,而是来了解一些他们的基本使用。 stack 模板类的定义在 stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元 素类型是必要的,在不指定容器类型时,默认的容器类型为deque。 定义stack 对象的示例代码如下: stack stack stack 的基本操作有: 入栈,如例:s.push(x); 出栈,如例:s.pop();注意,出栈操作只是删除栈顶元素,并不返回该元素。 访问栈顶,如例:s.top() 判断栈空,如例:s.empty(),当栈空时,返回true。 访问栈中的元素个数,如例:s.size() 下面是用string 和stack 写的解题1064--Parencoding 的程序。 queue 模板类的定义在 定义queue 对象的示例代码如下: queue queue queue 的基本操作有: 入队,如例:q.push(x); 将x 接到队列的末端。 出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。 访问队首元素,如例:q.front(),即最早被压入队列的元素。 访问队尾元素,如例:q.back(),即最后被压入队列的元素。 判断队列空,如例:q.empty(),当队列空时,返回true。 访问队列中的元素个数,如例:q.size() 在 定义priority_queue 对象的示例代码如下: priority_queue priority_queue< pair priority_queue priority_queue 的基本操作与queue 相同。 初学者在使用priority_queue 时,最困难的可能就是如何定义比较算子了。如果是基本数据类型,或已定义了比较运算符的类,可以直接用STL 的less算子和greater 算子——默认为使用less 算子,即小的往前排,大的先出队。如果要定义自己的比较算子,方法有多种,这里介绍其中的一种:重载比较运算符。优先队列试图将两个元素x 和y 代入比较运算符(对less 算子,调用x 看下面这个简单的示例: 输出结果为: 4 4 3 1 5 4 2 2 5 3 3 6 如果我们把第一个例子中的比较运算符重载为: bool operator < (const T &t1, const T &t2){ return t1.z > t2.z; // 按照z 的顺序来决定t1 和t2 的顺序 } 则第一个例子的程序会得到和第二个例子的程序相同的输出结果。 再回顾一下用优先队列实现的题1067--Ugly Numbers 的代码: 在STL 的头文件中定义了模板类map 和multimap,用有序二叉树来存贮类型为pair 1、定义map 对象,例如: map 2、向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。 3、查找元素对,例如: int i = m[key]; 要注意的是,当与该键值相匹配的元素对不存在时,会创建键值为key 的元素对。map 和end 操作)。 4、删除元素对,例如: m.erase(key);删除与指定key 键值相匹配的元素对,并返回被删除的元素的个数。 m.erase(it);删除由迭代器it 所指定的元素对,并返回指向下一个元素对的迭代器。 看一段简单的示例代码: 由于STL--algorithm较长 另加一篇详解ACM/ICPC 竞赛之STL--stack/queue
1、stack
#include
2、queue
3、priority_queue
#include
#include
ACM/ICPC 竞赛之STL--map
#include
再看一段简单的示例代码:#include