程序设计竞赛中常用的STL汇总
说明:文章篇幅有些长,请根据需要和目录选择性阅读!以下的所有STL
模板按照C++0x/11的标准来的,部分含有C++98的特性。在刷题或者考试的时候,请仔细看是否支持C++0x/11,否则会编译错误 2333333;如果竞赛不开编译优化的话,那就GG了。另外,由于是为了比赛或者考试,只是在尽量的短的时间内通过,所以不考虑工程上的一些特性,因此在实际项目中,尽量规范使用模板。另外,这些STL
在使用上不是特别符合STL
的正真标准,毕竟目的在前面说过了,实际规范用法和STL各个部分的意义请参照Effective STL这本书,我在后期的博客中会写一些总结笔记,也可以参考我后期的博客。个人对于STL比较推崇,,,,dalao勿喷,,,比较倾向于工程。。。
基础数据结构
线性结构
std::vector
简介:
可变长度的数组,支持随机访问,从尾部的插入和删除速度较快。邻接表建图可以用std::vector
完成。
构造函数:
std::vector<int> first; // 空的int型
std::vector<int> second(10, 100); // 含有10个值为100的int型,不指定初始值默认为0
std::vector<int> third(second.begin(), second.end()); // 复制区间的元素,int型
std::vector<int> fourth(third); // 复制构造函数,直接复制third
std::vector<int> fifth{1, 2, 3, 4 };// 初始化列表,5个元素值为 1 2 3 4 5
操作
operator=
给整个vector
赋值
vector& operator= (const vector& x);
vector& operator= (vector&& x);
vector& operator= (initializer_list<value_type> il);
迭代器:
begin()
指向第一个元素end()
指向最后一个元素的后一位,空的,没有任何元素!cbegin()
常指针,指向第一个元素cend()
常指针,位置同end()
容量:
size()
返回当前元素个数max_size()
返回当前系统当前情况可以容纳某类型元素最多的个数(竞赛中一般用不到i)resize()
重新分配元素个数void resize (size_type n); // 更改元素个数 void resize (size_type n, const value_type& val); // 更改元素个数,并指定值
如果元素少于原先的,直接从尾部删除,此时指定
val
是无效的。如果多余原先的,不指定val
默认新添加的为0
,否则新添加的是val
。empty()
是否为空判断,空返回true
,否则返回false
元素访问
operator[]
同数组下标访问,返回元素的引用at()
作用同operator[]
front()
返回第一个元素的引用back()
返回最后一个元素的引用
基本操作
assign()
作用基本同构造函数,不过可以直接运行中调用,且不能列表初始化push_back(const T& val)
或者push_back(T&&)
,把元素加入尾部pop_back()
把尾部元素删除insert
插入元素,注意,位置只能使用迭代器,返回新插入第一个元素的位置iterator insert (const_iterator position, const value_type& val); iterator insert (const_iterator position, size_type n, const value_type& val); template <class InputIterator> iterator insert (const_iterator position, InputIterator first, InputIterator last); iterator insert (const_iterator position, value_type&& val); iterator insert (const_iterator position, initializer_list<value_type> il);
position
是迭代器表示的元素的位置,val
是插入的元素,n
是插入元素的个数eraser
删除指定位置的元素,位置只能用迭代器表示,制定元素被删除后,新补充上的元素的位置。iterator erase (const_iterator position); iterator erase (const_iterator first, const_iterator last);
swap
交换两个有相同类型数据的vector
void swap (vector& x);
clear
删除vector
中所有的元素。
std::list
简介:
双向链表,不支持随机访问。
构造函数
与vector
的构造函数格式相同。
迭代器
同vector
容量
同vector
元素访问
front()
返回链首元素的引用back()
返回链尾元素的引用
操作
operator=
给整个链表赋值list& operator= (const list& x); list& operator= (list&& x); list& operator= (initializer_list<value_type> il);
assign()
同vector
resize
重新分配空间void resize (size_type n); void resize (size_type n, const value_type& val);
eraser()
删除指定位置元素iterator erase (const_iterator position); iterator erase (const_iterator first, const_iterator last);
push_front
表头插入元素void push_front (const value_type& val); void push_front (value_type&& val);
pop_front
删除表头元素push_back
尾部插入元素void push_back (const value_type& val); void push_back (value_type&& val);
pop_back
删除尾部元素insert
解释和vector
的一样iterator insert (const_iterator position, const value_type& val); iterator insert (const_iterator position, size_type n, const value_type& val); template <class InputIterator> iterator insert (const_iterator position, InputIterator first, InputIterator last); iterator insert (const_iterator position, value_type&& val); iterator insert (const_iterator position, initializer_list<value_type> il);
eraser
删除元素,解释参照vector
iterator erase (const_iterator position); iterator erase (const_iterator first, const_iterator last);
swap
交换两个链表void swap (list& x);
resize()
重新分配空间,解释参照vector
void resize (size_type n); void resize (size_type n, const value_type& val);
clear
清空表
新增操作
remove
删除指定元素void remove (const value_type& val);
链表中删除值是
val
的元素remove_if
删除满足条件的元素template <class Predicate> void remove_if (Predicate pred);
pred
返回true
的时候,删除该元素#include <bits/stdc++.h> using namespace std; inline bool cmp(const int &x) { //删除所有奇数 return x % 2 != 0; } int main() { list<int>l{1, 2, 3, 4, 5, 6, 6, 6, 6, 8, 9}; l.remove_if(cmp); for(list<int>::iterator it = l.begin(); it != l.end(); it++) { cout << *it << endl; } return 0; }
unique
删除重复元素,只保留重复元素中的第一个void unique(); // 一般自带类型的元素 template <class BinaryPredicate> // 自定义条件元素 void unique (BinaryPredicate binary_pred);
#include <bits/stdc++.h> using namespace std; inline bool same(const double &x, const double &y) { // 删除整数部分一样的 return int(x) == int(y); } int main() { list<double>l{1.1, 2.2, 3.3, 4.1, 5.4, 6.1, 6.2, 6.3, 6.5, 8.0, 9.0}; l.unique(same); for(list<double>::iterator it = l.begin(); it != l.end(); it++) { cout << *it << endl; } return 0; }
merge
有序合并两个链表,归并排序的合并部分。void merge (list& x); void merge (list&& x); template <class Compare> void merge (list& x, Compare comp); template <class Compare> void merge (list&& x, Compare comp);
comp
比较函数是自定义规则的#include <bits/stdc++.h> using namespace std; // 合并规则是整数部分的递减 inline bool cmp(const double &x, const double &y) { return int(x) > int(y); } int main() { list<double> l1{1.1, 3.3, 5.5, 7.8, 9.2}; list<double> l2{2.2, 4.4, 6.6, 8.3, 10.1}; l1.merge(l2, cmp); for(list<double>::iterator it = l1.begin(); it != l1.end(); it++) { cout << *it << " "; } return 0; } // 2.2 4.4 6.6 8.3 10.1 1.1 3.3 5.5 7.8 9.2
注意
merge
使用比较函数的是有,只有l1
满足条件的时候,l1
的迭代器移动。sort
排序操作void sort(); template <class Compare> void sort (Compare comp);
reverse
链表顺序逆序
std::queue
简介:
数据结构中先入先出的队列,不允许随机访问。
构造函数:
不允许使用初始化列表,不允许使用区间复制。只能使用默认构造函数或者使用复制构造复制其他已有的队列。
成员函数:
empty
是否为空的判断push
元素入队size()
当前元素个数front()
返回队首元素的引用back()
返回队尾元素的引用pop()
队尾元素出队swap()
交换两个队列元素
std::deque
简介:
双端队列,实现方式与std::queue
不同,构造方式和vector
一样,允许随机访问,与vector
相比,多了push_front
pop_front
两个函数。用到的机会较少,需要时查找标准库
std::stack
简介:
数据结构中的栈,先入后出。实现方式和std::queue
类似,构造方式和std::queue
相同。不允许随机访问。
成员函数:
empty()
判断是否为空size()
返回当前元素个数top()
返回栈顶元素的引用push()
元素入栈pop()
元素出栈
std::string
简介:
std::string
是C++对于字符串的封装,尽量使用std::string
来代替传统的字符数组。
构造函数
string(); // 默认构造函数
string (const string& str); // 复制构造函数
// 从str的pos开始复制长度为npos的字符串
string (const string& str, size_t pos, size_t len = npos);
string (const char* s); // 内容初始化为C风格的s字符串的内容
string (const char* s, size_t n);// 同上,n表示要获取的字符串个数
string (size_t n, char c); // 加入n个相同的字符c
template <class InputIterator> // 复制区间
string (InputIterator first, InputIterator last);
string (initializer_list<char> il);// 初始化列表
string (string&& str) noexcept; // 右值
赋值操作
operator=
用新的字符串覆盖当前字符
std::string s1="hello world !";
std::string s2="x";
std::string s3=s1+'c'+s2+" test";
容量:
size()
字符的个数length()
字符的个数resize()
重新分配空间void resize (size_t n); void resize (size_t n, char c);
解释同
std::vector
clear()
清空empty()
判断是否为空
元素访问:
operator[]
随机访问,返回引用at()
随机访问,返回引用front()
第一个元素back()
最后一个元素
一般操作
operator=
string& operator+= (const string& str); // 追加string string& operator+= (const char* s); // 追加C风格的string string& operator+= (char c); // 追加单个字符 string& operator+= (initializer_list<char> il);// 追加初始化列表
append()
string& append (const string& str); // 追加string // 从str的第subpos开始追加sublen个长度 string& append (const string& str, size_t subpos, size_t sublen); string& append (const char* s); // 追加C风格的string string& append (const char* s, size_t n);// 从s开始追加n个字符 string& append (size_t n, char c); // 追加n个字符c template <class InputIterator> // 追加区间 string& append (InputIterator first, InputIterator last); string& append (initializer_list<char> il); // 追加初始化列表
insert
插入。功能太多,直接找标准库eraser
删除string& erase (size_t pos = 0, size_t len = npos); iterator erase (const_iterator p); iterator erase (const_iterator first, const_iterator last);
replace
替换操作,找标准库还有其他的一些操作,但是在竞赛里几乎不用,在这里不再提了。
getline:
一般读取字符串使用该函数:
istream& getline (istream& is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream& is, string& str);
istream& getline (istream&& is, string& str);
没有delim
用于读取一整行,delim
表示读取到这个字符就停止,一般处理特殊字符。
string str;
getline(std::cin, str);
std::forward_list
单向链表,几乎不用
std::array
C++固定长度的数组,一般使用std::vector
代替了
非线性结构
堆的有关操作
这些操作的思路和算法导论第三版所讲的基本类似。
std::make_heap
简介:
把某段范围内的元素按照堆的序列进行排放,并更改迭代器的索引。
操作:
template <class RandomAccessIterator> // 默认的构造函数
void make_heap (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare> // 自定义构造函数
void make_heap (RandomAccessIterator first, RandomAccessIterator last,
Compare comp );
具有最高优先级的元素总是在堆顶部,默认构造函数默认重载运算符operator<
,具有最高优先级的元素与其他所有优先级的元素相比,总是返回false
,这点在构造比较函数comp
的时候要格注意!
comp
是一个二元函数(含有两个参数),返回bool
类型。在比较函数comp
中,最好是声明第一个参数怎样比第二个参数小,即operator<
意义上的。comp
可以是函数指针或者函数对象。
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data{0};
bool operator<(const Node& tmp) { // 重载默认比较操作<
return data < tmp.data;
}
};
struct Node1 {
int data{0};
};
inline bool comp(const Node1& a, const Node1& b) { // 自定义比较函数
return a.data < b.data;
}
int main() {
vector<int>v1{1, 2, 6, 7, 9, 8, 0, 4, 3, 5};
make_heap(v1.begin(), v1.end()); // heapify整数,默认形式
cout << "heapify v1:" << v1.front() << endl;
vector<Node>v2;
for(int i = 0; i < 10; ++i) {
Node tmp;
tmp.data = i;
v2.push_back(tmp);
}
make_heap(v2.begin(), v2.end()); // heapify自定义的类型
cout << "heapify v2:" << v2.front().data << endl;
vector<Node1>v3;
for(int i = 0; i < 10; ++i) {
Node1 tmp;
tmp.data = i;
v3.push_back(tmp);
}
make_heap(v3.begin(), v3.end(), comp); // heapify自定义比较函数
cout << "heapify v3:" << v3.front().data << endl;
int h[5] = {1, 2, 4, 5, 3};
make_heap(h, h + 5); // 普通数组的堆化
for(int i = 0; i < 5; ++i) {
cout << h[i] << " ";
}
cout << endl;
return 0;
}
std::push_heap
简介:
向容器的尾部添加元素,然后调用该函数,重新维护堆的性质。可以理解为把元素的范围从[first,last-1)
扩充到[first,last)
使用方式:
template <class RandomAccessIterator>
void push_heap (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
void push_heap (RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
comp
的用法和std::make_heap
一样。默认重载operator<
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{1, 3, 2, 4, 5, 7, 6, 8, 0, 10};
make_heap(v.begin(), v.end() - 1); // 先不添加10,heapify元素
cout << "heapify:" << v.front() << endl; // 堆顶元素是8
push_heap(v.begin(), v.end()); // 添加一个元素后,堆化
cout << "add elem:" << v.front() << endl; // 堆顶元素是10
return 0;
}
std::pop_heap
简介:
std::push_heap
的逆操作。元素的范围从[first,last)
缩减到[first,last-1)
。实际上是从容器内部调整完元素之后,舍弃最后一个。
使用方式:
template <class RandomAccessIterator>
void pop_heap (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
void pop_heap (RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
comp
的用法和std::make_heap
一样。默认重载operator<
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{1, 3, 2, 4, 5, 7, 6, 8, 0, 10};
make_heap(v.begin(), v.end());
cout << "heapify:" << v.front() << endl;
pop_heap(v.begin(), v.end());
v.pop_back();
cout << "delete elem:" << v.front() << endl;
return 0;
}
std::sort_heap
简介:
把已经容器内已经堆化的范围按照升序排列。
使用方式:
template <class RandomAccessIterator>
void sort_heap (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
void sort_heap (RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
comp
的用法和std::make_heap
一样。默认重载operator<
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{1, 3, 2, 4, 5, 7, 6, 8, 0, 10, 9};
make_heap(v.begin(), v.end()); // 必须先进行堆化
sort_heap(v.begin(), v.end());
for(int i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl;
return 0;
}
std::priority_queue
简介:
可以认为是对上述堆操作的一个封装。把零散的堆操作封装到一个类之中。
定义方式:
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;
T
是数据类型; Container
是容器,默认为std::vector
;Compare
是比较函数,规则与std::make_heap
的一致,因此默认重载operator<
构造:
构造函数种类较多,在这里只列举三个常用的。构造时也可以按照定义的方式构造,这种方式反而比较常用。
// ctnr的内容自动建立堆序加入优先队列
priority_queue (const Compare& comp, const Container& ctnr);
template <class InputIterator>
priority_queue (InputIterator first, InputIterator last,
const Compare& comp, const Container& ctnr);
explicit priority_queue (const Compare& comp = Compare(),
Container&& ctnr = Container());
template <class InputIterator>
priority_queue (InputIterator first, InputIterator last,
const Compare& comp, Container&& ctnr = Container());
举例说明:
// constructing priority queues
#include <iostream> // std::cout
#include <queue> // std::priority_queue
#include <vector> // std::vector
#include <functional> // std::greater
class mycomparison
{
bool reverse;
public:
mycomparison(const bool& revparam=false)
{reverse=revparam;}
bool operator() (const int& lhs, const int&rhs) const
{
if (reverse) return (lhs>rhs);
else return (lhs<rhs);
}
};
int main ()
{
int myints[]= {10,60,50,20};
std::priority_queue<int> first;
std::priority_queue<int> second (myints,myints+4);
std::priority_queue<int, std::vector<int>, std::greater<int> >
third (myints,myints+4);
// using mycomparison:
typedef std::priority_queue<int,std::vector<int>,mycomparison> mypq_type;
mypq_type fourth; // less-than comparison
mypq_type fifth (mycomparison(true)); // greater-than comparison
return 0;
}
成员函数:
empty()
判断是否为空size()
返回当前元素个数top()
返回堆顶元素的常引用push()
添加元素入堆pop()
堆顶元素出队void swap (priority_queue& x) noexcept
交换两个堆的元素
std::set
简介:
维护了一颗平衡二叉搜索树–红黑树,元素的键值key
必须是唯一的。在容器中的元素的值不能被立即改变,但是可以向容器内添加或者删除元素。一般来说,std::set
的操作要比std::unordered_set
操作慢,但是我们可以在它的子集上直接进行迭代操作。默认重载运算符operator<
或者less<T>
,一般结构内部自定义operator()
构造:
template < class T, // set::key_type/value_type
class Compare = less<T>, // set::key_compare/value_compare
class Alloc = allocator<T> // set::allocator_type
> class set;
一般来说,我们自定义的时候,只需要现实的声明元素类型T
和比较函数Compare
即可。在构造的时候,可以声明需要的范围。
// constructing sets
#include <iostream>
#include <set>
bool fncomp (int lhs, int rhs) {return lhs<rhs;}
struct classcomp {
bool operator() (const int& lhs, const int& rhs) const
{return lhs<rhs;}
};
int main ()
{
std::set<int> first; // empty set of ints
int myints[]= {10,20,30,40,50};
std::set<int> second (myints,myints+5); // range
std::set<int> third (second); // a copy of second
std::set<int> fourth (second.begin(), second.end()); // iterator ctor.
std::set<int,classcomp> fifth; // class as Compare
bool(*fn_pt)(int,int) = fncomp;
std::set<int,bool(*)(int,int)> sixth (fn_pt); // function pointer as Compare
return 0;
}
成员函数:
insert()
插入元素或者区间,不会插入重复的元素。pair<iterator,bool> insert (const value_type& val); // 返回插入的位置,不重复返回true pair<iterator,bool> insert (value_type&& val); iterator insert (const_iterator position, const value_type& val);// 指定位置为根插入 iterator insert (const_iterator position, value_type&& val); template <class InputIterator> // 插入区间 void insert (InputIterator first, InputIterator last); void insert (initializer_list<value_type> il);
eraser()
删除指定的元素或者区间:iterator erase (const_iterator position); // 删除指定位置的元素,返回删除的位置 size_type erase (const value_type& val); // 删除键值为val的元素 iterator erase (const_iterator first, const_iterator last); // 删除指定的区间
operator=
集合之间的赋值迭代器,参照
std::vector
的clear
清空所有的元素find()
寻找指定值的元素:const_iterator find (const value_type& val) const; iterator find (const value_type& val);
找不到返回
set::end()
count()
返回具有特定值元素的个数,因为std::set
的元素键值是唯一的,所以只能返回1或者0lower_bound
和upper_bound
:直接参考代码// set::lower_bound/upper_bound #include <iostream> #include <set> int main () { std::set<int> myset; std::set<int>::iterator itlow,itup; for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90 itlow=myset.lower_bound (30); // ^ itup=myset.upper_bound (60); // ^ myset.erase(itlow,itup); // 10 20 70 80 90 std::cout << "myset contains:"; for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0;
std::multiset
简介:
实现一个二叉搜索树,允许已有多个键值相同的元素存在,其余的和std::set
一样。
操作:
基本与std::set
一样,注意下count()
函数,返回值可能大于1。其余还有一些细微的差别,在这里暂时不讲解,可自行Google或百度。find()
函数返回找到的第一个键值的位置。
equal_range()
简介:
返回具有某个键值的区间,这个在多个元素的情况下很常用
使用方式:
pair<const_iterator,const_iterator> equal_range (const value_type& val) const;
pair<iterator,iterator> equal_range (const value_type& val);
以std::pair
的方式返回具有val
值的区间,代码举例:
// multiset::equal_elements
#include <iostream>
#include <set>
typedef std::multiset<int>::iterator It; // aliasing the iterator type used
int main ()
{
int myints[]= {77,30,16,2,30,30};
std::multiset<int> mymultiset (myints, myints+6); // 2 16 30 30 30 77
std::pair<It,It> ret = mymultiset.equal_range(30); // ^ ^
mymultiset.erase(ret.first,ret.second); // 删除指定区间的元素
std::cout << "mymultiset contains:";
for (It it=mymultiset.begin(); it!=mymultiset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
// multiset contains: 2 16 77
std::map
简介:
C++的字典,键值key
和元素具有唯一的映射关系。映射关系靠std::pair
(看后文)来实现。键值key
是用来排序和标识映射的,因此必须是唯一的,同样也说明了该结构只支持一对一的映射关系。可以直接通过operator[]
来访问每个std::pair
。
template < class Key, // map::key_type
class T, // map::mapped_type
class Compare = less<Key>, // map::key_compare
class Alloc = allocator<pair<const Key,T> > // map::allocator_type
> class map;
构造方式:
直接参照代码:
// constructing maps
#include <iostream>
#include <map>
bool fncomp (char lhs, char rhs) {return lhs<rhs;} // 自定义比较函数
struct classcomp {
bool operator() (const char& lhs, const char& rhs) const // 自定义比较结构
{return lhs<rhs;}
};
int main ()
{
std::map<char,int> first;
first['a']=10;
first['b']=30;
first['c']=50;
first['d']=70;
std::map<char,int> second (first.begin(),first.end());
std::map<char,int> third (second);
std::map<char,int,classcomp> fourth; // 使用比较结构
bool(*fn_pt)(char,char) = fncomp;
std::map<char,int,bool(*)(char,char)> fifth (fn_pt); // 使用比较函数
return 0;
}
迭代器:
参照std::vector
操作:
empty()
判断是否为空size()
返回当前有序组的个数operator[]
按下标访问insert()
插入元素pair<iterator,bool> insert (const value_type& val); // 直接插入有序组,返回插入元素 template <class P> pair<iterator,bool> insert (P&& val);// 右值插入 iterator insert (const_iterator position, const value_type& val);// 特定位置插入元素 template <class P> iterator insert (const_iterator position, P&& val);// 插入右值 template <class InputIterator> // 插入区间,自动忽略掉键值重复的 void insert (InputIterator first, InputIterator last); void insert (initializer_list<value_type> il); // 插入初始化列表
eraser()
删除指定元素:iterator erase (const_iterator position); // 按照位置删除 size_type erase (const key_type& k); // 按照键值删除 iterator erase (const_iterator first, const_iterator last); // 删除指定区间
clear()
清空字典swap()
交换两个字典的元素find()
寻找特定的值,按照键值查找,并返回位置,没找到返回std::map::end()
iterator find (const key_type& k); const_iterator find (const key_type& k) const;
count()
返回具有特殊键值的元素的个数。由于std::map
的键值是唯一的,因此返回值只能是1或者0.lower_bound()
和upper_bound()
返回指定的区间范围。
std::multimap
简介:
基本与std::map
一样,注意下count()
函数,返回值可能大于1。其余还有一些细微的差别,在这里暂时不讲解,可自行Google或百度。find()
函数返回找到的第一个键值的位置。
操作:
equal_range()
简介:
返回具有某个键值的区间,这个在多个元素的情况下很常用
使用方式:
pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
pair<iterator,iterator> equal_range (const key_type& k);
以std::pair
的方式返回具有val
值的区间,代码举例:
// multimap::equal_range
#include <iostream>
#include <map>
int main ()
{
std::multimap<char,int> mymm;
mymm.insert(std::pair<char,int>('a',10));
mymm.insert(std::pair<char,int>('b',20));
mymm.insert(std::pair<char,int>('b',30));
mymm.insert(std::pair<char,int>('b',40));
mymm.insert(std::pair<char,int>('c',50));
mymm.insert(std::pair<char,int>('c',60));
mymm.insert(std::pair<char,int>('d',60));
std::cout << "mymm contains:\n";
for (char ch='a'; ch<='d'; ch++)
{
std::pair <std::multimap<char,int>::iterator, std::multimap<char,int>::iterator> ret;
ret = mymm.equal_range(ch);
std::cout << ch << " =>";
for (std::multimap<char,int>::iterator it=ret.first; it!=ret.second; ++it)
std::cout << ' ' << it->second;
std::cout << '\n';
}
return 0;
}
有序对和位运算
std::pair
简介:
C++中的有序二元组。
template <class T1, class T2> struct pair;
构造方式:
直接参照代码:
std::pair <std::string,double> product1; // default constructor
std::pair <std::string,double> product2 ("tomatoes",2.30); // value init
std::pair <std::string,double> product3 (product2); // copy constructor
product1 = std::make_pair(std::string("lightbulbs"),0.99); // using make_pair (move)
product2.first = "shoes"; // the type of first is string
product2.second = 39.90; // the type of second is double
操作:
swap()
直接交换两个二元组operator=
直接赋值first
返回第一个元素,不是函数,是关键字second
返回第二个元素,不是函数,是关键字
std::bitset
简介:
位运算可以基本上用这个代替了。个人比较倾向于库函数233333333.
构造:
直接给出代码:
// constructing bitsets
#include <iostream> // std::cout
#include <string> // std::string
#include <bitset> // std::bitset
int main ()
{
std::bitset<16> foo; // 默认全是0,指定位数
std::bitset<16> bar (0xfa2); // 16进制表示
std::bitset<16> baz (std::string("0101111001")); // 字符串也就可以的
std::cout << "foo: " << foo << '\n';
std::cout << "bar: " << bar << '\n';
std::cout << "baz: " << baz << '\n';
return 0;
}
/*
foo: 0000000000000000
bar: 0000111110100010
baz: 0000000101111001
*/
常见的操作:
直接上代码吧。。。。
// bitset operators
#include <iostream> // std::cout
#include <string> // std::string
#include <bitset> // std::bitset
int main ()
{
std::bitset<4> foo (std::string("1001"));
std::bitset<4> bar (std::string("0011"));
std::cout << (foo^=bar) << '\n'; // 1010 (XOR,assign)
std::cout << (foo&=bar) << '\n'; // 0010 (AND,assign)
std::cout << (foo|=bar) << '\n'; // 0011 (OR,assign)
std::cout << (foo<<=2) << '\n'; // 1100 (SHL,assign)
std::cout << (foo>>=1) << '\n'; // 0110 (SHR,assign)
std::cout << (~bar) << '\n'; // 1100 (NOT)
std::cout << (bar<<1) << '\n'; // 0110 (SHL)
std::cout << (bar>>1) << '\n'; // 0001 (SHR)
std::cout << (foo==bar) << '\n'; // false (0110==0011)
std::cout << (foo!=bar) << '\n'; // true (0110!=0011)
std::cout << (foo&bar) << '\n'; // 0010
std::cout << (foo|bar) << '\n'; // 0111
std::cout << (foo^bar) << '\n'; // 0101
return 0;
}
其他的一些操作
operator[]
获取指定位置的元素的引用,可以更改值count()
返回1的个数,位置从右往左!!!!!size()
返回长度test()
测试某个位是否是1any()
测试是否有1none()
测试是否都是0flip()
反转某个bit位,如果不添加参数,反转所有bit位(等效成取反)。位置从右往左reset()
重置某个bit位,不添加参数默认全部重置为0。位置从右往左
哈希
由于哈希不被C++标准库支持,貌似在竞赛里也不能用了23333333. 需要的自己搜一下std::hash_set
和std::hash_map
吧,不过哈希貌似用的不是太多。。。。
排序
基础排序算法
std::sort
最常用的快速排序,默认从小到大,复杂结构比较需要重载operator<
,直接贴代码:
// sort algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::sort
#include <vector> // std::vector
bool myfunction (int i,int j) { return (i<j); } // 自定义比较函数
struct myclass {
bool operator() (int i,int j) { return (i<j);} // 重载复杂结构的比较运算符
} myobject;
int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33
// using default comparison (operator <):
std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33
// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction);// 12 32 45 71(26 33 53 80)
// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
std::stable_sort
归并排序算法,是稳定排序。有特殊要求在用这个,需要额外的内存空间,用法和std:;sort
一样,不再赘述。
std::sort_heap
堆排序,需要待排序的容器元素已经满足堆的结构才行。前面堆结构讲解了。
std::partial_sort
简介:
局部排序,确定出区间[first,middle)
元素的个数M
,把所有的N
个元素的前M
的最小的按照升序排列,放在前M
个位置上,其余的元素放在后面,相对位置不变。算法的复杂度是
Nlog2M
N
log
2
M
template <class RandomAccessIterator>
void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
void partial_sort (RandomAccessIterator first, RandomAccessIterator middle,
RandomAccessIterator last, Compare comp);
也可以自定义优先级,代码说明:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{0, 1, 4, 3, 2, 5, 8, 7, 6, 9};
// 定义从大到小
partial_sort(v.begin(), v.begin() + 5, v.end(), greater<int>());
for(int i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl;
return 0;
}
// 9 8 7 6 5 0 1 2 3 4
辅助排序功能
std::partition
简介:
类似快速排序中选择主元的操作(自己看算法导论23333)。不过在这里把主元的选择改成了自定义条件,及满足某个条件的元素放到容器的前面,不满足某个条件的元素放到容器后面,这是不稳定的!!!
直接上代码:
#include <bits/stdc++.h>
using namespace std;
bool is_odd(const int& x) { // 自定义条件
return x % 2 == 1;
}
int main() {
vector<int>v{0, 1, 4, 3, 2, 5, 8, 7, 6, 9};
partition(v.begin(), v.end(), is_odd); // 奇数在前,偶数在后
for(int i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl;
return 0;
}
// 9 1 7 3 5 2 8 4 6 0
std::stable_partition
简介:
和std::partiton
几乎一样,不过这是稳定的。。
std::merge
简介:
类似于归并排序中的合并两个有序表的操作(不懂的看算法导论)。默认升序排列,重载运算符operator<
。归并进入的容器需要有足够的空间!!!!
构造方式:
// 参数为两个区间的范围,result是新的放置元素的容器(参考归并排序的过程)
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
// 在上述的基础上,增加了比较函数
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator merge (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
代码说明:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v1{9, 7, 5, 3, 1};
vector<int>v2{10, 8, 6, 4, 2};
vector<int>v(10); // 需要有足够的空间!!!
// 自定义从大到小的顺序
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin(), greater<int>());
for(int i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl;
return 0;
}
std::inplace_merge
内部合并:
把一个容器内的两个递归有序的子序列[first,middle)
和[middle,last
直接在原来容器的内部进行归并。
// 输入区间
template <class BidirectionalIterator>
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last);
// 输入区间和比较方法
template <class BidirectionalIterator, class Compare>
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last, Compare comp);
直接上代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int t = v.size();
inplace_merge(v.begin(), v.begin() + t / 2, v.end());
for(int i = 0; i < t; ++i) {
cout << v[i] << " ";
}
cout << endl;
return 0;
}
// 1 2 3 4 5 6 7 8 9 10
std::make_heap
参照前面堆的说明。。。
查找
单个元素查找
std::find
简介:
在区间查找特殊值的元素,并返回第一个特殊值位置,没有返回end()
template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val);
std::find_if
简介:
按照指定条件查找元素,并返回第一个满足条件的位置,没有返回end()
// pred是比较条件
template <class InputIterator, class UnaryPredicate>
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);
std::count
简介:
返回指定区间内,关键字满足要求值的元素的个数。默认重载operator==
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count (InputIterator first, InputIterator last, const T& val);
std::count_if
简介:
返回满足条件的元素的个数
template <class InputIterator, class UnaryPredicate>
typename iterator_traits<InputIterator>::difference_type
count_if (InputIterator first, InputIterator last, UnaryPredicate pred);
std::search_n
简介:
查找满足条件的元素,可以选择返回满足条件的第几个的位置返回,默认重载operator==
// 区间范围,想要第count个满足条件的返回,val是条件值
template <class ForwardIterator, class Size, class T>
ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
Size count, const T& val);
// pred是自定义条件函数
template <class ForwardIterator, class Size, class T, class BinaryPredicate>
ForwardIterator search_n ( ForwardIterator first, ForwardIterator last,
Size count, const T& val, BinaryPredicate pred );
代码实例:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{1, 3, 5, 7, 9, 3, 3, 5, 2, 4, 6, 8, 10};
vector<int>::iterator it = search_n(v.begin(), v.end(), 2, 3);
cout << (it - v.begin()) << endl; // 下标等效成从0开始。。。。
return 0;
}
// 5
std::adjacent_find
简介:
在给定的区间查找前两个重复的元素,并返回这两个重复元素中第一个的位置。
// 输入区间
template <class ForwardIterator>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last);
// 输入区间,并给出重复条件
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last,
BinaryPredicate pred);
代码说明:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{1, 3, 5, 7, 9, 3, 3, 5, 2, 4, 6, 8, 10};
vector<int>::iterator it = adjacent_find(v.begin(),v.end());
cout << *it << endl;
return 0;
}
// 3
std::binary_search
简介:
在有序的区间内进行二分查找。返回bool
值。comp
是二元的比较函数。
// 输入区间和要查找的值
template <class ForwardIterator, class T>
bool binary_search (ForwardIterator first, ForwardIterator last,
const T& val);
// 输入区间和要查找的条件
template <class ForwardIterator, class T, class Compare>
bool binary_search (ForwardIterator first, ForwardIterator last,
const T& val, Compare comp);
代码实例:
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data{0};
char c{'\0'};
};
bool cmp(const Node& a, const Node& b) {
return a.data == b.data;
}
int main() {
vector<Node>a(10);
for(int i = 0; i < 10; ++i) {
a[i].data = i;
}
Node tmp{5, '\0'};
if(binary_search(a.begin(), a.end(), tmp, cmp)) {
cout << "ok" << endl;
}
return 0;
}
std::min_element\std::max_element
简介:
查找区间的最值,并返回位置。
// 输入区间
template <class ForwardIterator>
ForwardIterator min_element (ForwardIterator first, ForwardIterator last);
// 输入区间和比较条件
template <class ForwardIterator, class Compare>
ForwardIterator min_element (ForwardIterator first, ForwardIterator last,
Compare comp);
区间查找
std::search
简介:
在指定的区间[first1,last1)]
内寻找满足条件的子区间[first2,last2)
。 如果找到了,返回[first1,last1)
中第一个满足条件的子区间的first
迭代器,否则返回last1
。
使用方式:
template <class ForwardIterator1, class ForwardIterator2>
// first1,last1是待查询的区间,first2,last2是目标区间
ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2);
// 增加一个包含两个参数的自定义比较函数pred
template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
BinaryPredicate pred);
直接上代码:
#include <bits/stdc++.h>
using namespace std;
struct Node { // 自定义结构
int data{0};
char c{'\0'};
};
bool cmp(const Node& a, const Node& b) { // 自定义比较函数
return a.data == b.data;
}
int main() {
vector<int>a(10);
for(int i = 0; i < 10; ++i) {
a[i] = i;
}
vector<int>b{3, 4, 5, 6};
// 找到了
vector<int>::iterator it = search(a.begin(), a.end(), b.begin(), b.end());
if(it != a.end()) {
cout << "ok" << endl;
} else
cout << "no" << endl;
vector<Node>v(10);
for(int i = 0; i < 10; ++i) {
v[i].data = i;
}
vector<Node>v1(3);
for(int i = 0; i < 3; ++i) {
v1[i].data = i + 10;
}
// 找不到,返回last1
vector<Node>::iterator it1 = search(v.begin(), v.end(), v1.begin(), v1.end(), cmp);
if(it1 != v.end()) {
cout << "ok" << endl;
} else
cout << "no" << endl;
return 0;
}
//ok
//no
std::find_end
简介:
与std::search()
用法一样,唯一的区别在于这个是返回最后一个满足条件的子区间的首地址
std::equal
简介:
[first1,last1)
区间的元素与从first2
起始的元素比较,如果匹配就返回true
,否则返回false
。
// first1和last1是目标区间,first2是匹配判断的起始区间
template <class InputIterator1, class InputIterator2>
bool equal (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2);
// pred是自定义比较函数
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool equal (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate pred);
直接上代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v1{5, 6, 7, 8};
vector<int>v2(10);
for(int i = 0; i < 10; ++i) {
v2[i] = i;
}
bool flag = equal(v1. begin(), v1.end(), v2.begin());// 不匹配
if(flag) {
cout << "ok" << endl;
} else {
cout << "no" << endl;
}
flag = equal(v1.begin(), v1.end(), v2.begin() + 5); // 匹配
if(flag) {
cout << "ok" << endl;
} else {
cout << "no" << endl;
}
return 0;
}
// no
// ok
std::equal_range
简介:
在区间[first,last)
中寻找所有值为val
的第一个子区间,返回std::pair
类型。没找到返回end
template <class ForwardIterator, class T>
pair<ForwardIterator,ForwardIterator>
equal_range (ForwardIterator first, ForwardIterator last, const T& val);
template <class ForwardIterator, class T, class Compare>
pair<ForwardIterator,ForwardIterator>
equal_range (ForwardIterator first, ForwardIterator last, const T& val,
Compare comp);
std::mismatch
简介:
把[first,last)
与从first2
开始的区间进行比较,返回第一个两个序列中不匹配的位置。,是一个std::pair
类型。
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2>
mismatch (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2);
// 增加了一个比较函数pred
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2>
mismatch (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate pred);
代码说明:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{3, 4, 5, 7};
vector<int>v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto pos = mismatch(v.begin(), v.end(), v1.begin() + 3);
cout << *pos.first << " " << *pos.second << endl;
return 0;
}
// 7 6
集合查找
std::find_first_of
简介:
返回在[first1,last1)
中,任何匹配上在范围[first2,last2)
的地址,找不到就返回last1
。
template <class InputIterator, class ForwardIterator>
InputIterator find_first_of (InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2);
template <class InputIterator, class ForwardIterator, class BinaryPredicate>
InputIterator find_first_of (InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
BinaryPredicate pred);
直接上代码:
// find_first_of example
#include <iostream> // std::cout
#include <algorithm> // std::find_first_of
#include <vector> // std::vector
#include <cctype> // std::tolower
bool comp_case_insensitive (char c1, char c2) {
return (std::tolower(c1)==std::tolower(c2));
}
int main () {
int mychars[] = {'a','b','c','A','B','C'};
std::vector<char> haystack (mychars,mychars+6);
std::vector<char>::iterator it;
int needle[] = {'A','B','C'};
// using default comparison:
it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3);
if (it!=haystack.end())
std::cout << "The first match is: " << *it << '\n';
// using predicate comparison:
it = find_first_of (haystack.begin(), haystack.end(),
needle, needle+3, comp_case_insensitive);
if (it!=haystack.end())
std::cout << "The first match is: " << *it << '\n';
return 0;
}
/*
The first match is: A
The first match is: a
*/
集合操作
说明:
以下所有的集合操作,都需要存储集合元素的容器是有序的。
std::set_intersection
简介:
求两个有序序列的交集。输入两个具有一致顺序的有序序列[first1,last1)
和[first2,last2)
,再输入一个存放交集结果的容器的起始地址result
,函数容器中,结束的地址。(直接看代码理解吧)
// 输入两个集合、容器
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
// 增加一个比较函数,是二值的
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
实例代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{3, 4, 5, 11};
vector<int>v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int>u(10);
auto stop = set_intersection(v.begin(), v.end(), v1.begin(), v1.end(), u.begin());
for(auto it = u.begin(); it != stop; ++it) { // 使用了返回的地址
cout << *it << " ";
}
cout << endl;
return 0;
}
// 3 4 5
输出序列的顺序是按照第一个输入序列来的,需要保证result
有足够的空间。
std::set_union
简介:
求两个集合的交集。输入和返回的参数同std::set_intersection
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_union (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
代码实例:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{4, 5, 11, 14};
vector<int>v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int>u(v.size() + v1.size()); // 注意保证空间充足
auto stop = set_union(v.begin(), v.end(), v1.begin(), v1.end(), u.begin());
u.resize(stop - u.begin()); // 这一句是可选的,在这里让并集删除多余的元素
for(auto it = u.begin(); it != stop; ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
// 0 1 2 3 4 5 6 7 8 9 11 14
std::set_difference
简介:
求集合的差。输入和返回的值类比std::set_inserection
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
代码实例:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{4, 5, 8, 9, 11, 14, 19, 40};
vector<int>v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int>u(v.size() + v1.size());
auto stop = set_difference(v.begin(), v.end(), v1.begin(), v1.end(), u.begin());
u.resize(stop - u.begin()); // 可选的,控制集合的最终容量
for(auto it = u.begin(); it != stop; ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
// 11 14 19 40
std::set_symmetric_difference
简介:
求集合的对等差分。参数和返回值参考std::set_inserection
。至于什么是对等差分,大家就自己Google或者百度吧 223333333.
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
template <class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
实例代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{4, 5, 8, 9, 11, 14, 19, 40};
vector<int>v1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int>u(v.size() + v1.size());
auto stop = set_symmetric_difference(v.begin(), v.end(), v1.begin(), v1.end(), u.begin());
u.resize(stop - u.begin()); // 可选的操作,控制最终结果容器的容量
for(auto it = u.begin(); it != stop; ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
// 0 1 2 3 6 7 11 14 19 40
排列组合
std::next_permutation
简介:
给出一个区间的下一个升序的字典序,如果还有下一个字典序,返回true
,否则返回false
// 输入一个原始序列
template <class BidirectionalIterator>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last);
// 增加一个自定义二值比较函数
template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last, Compare comp);
实例代码:
#include <bits/stdc++.h>
using namespace std;
bool comp(const char& a, const char& b) { // 自定义比较函数
return a > b;
}
int main() {
vector<int>v{1, 2, 3};
do {
cout << v[0] << v[1] << v[2] << endl;
} while(next_permutation(v.begin(), v.end()));
string str("cba");
do {
cout << str << endl;
} while(next_permutation(str.begin(), str.end(), comp)); // 字典序逆序
return 0;
}
/*
123
132
213
231
312
321
cba
cab
bca
bac
acb
abc
*/
std::prev_permutation
简介:
与std::next_permutation
用法一样,只是输出默认的前面的字典序列
区间
std::lower_bound
简介:
返回有序区间[first,last)
中,不小于指定值的最左侧位置的迭代器。没有返回last
// 输入区间和指定值
template <class ForwardIterator, class T>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
const T& val);
template <class ForwardIterator, class T, class Compare>
ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
const T& val, Compare comp);
实例代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{2, 1, 3, 6, 5, 4, 9, 8, 7, 0};
sort(v.begin(), v.end());
auto it = lower_bound(v.begin(), v.end(), 2);
cout << it - v.begin() << endl;
it = lower_bound(v.begin(), v.end(), 3);
cout << it - v.begin() << endl;
return 0;
}
// 2 3
std::upper_bound
简介:
返回有序[first,last)
区间中,大于指定元素的迭代器的位置,没有返回last
template <class ForwardIterator, class T>
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,
const T& val);
template <class ForwardIterator, class T, class Compare>
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,
const T& val, Compare comp);
代码实例:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{2, 1, 3, 6, 5, 4, 9, 8, 7, 0};
sort(v.begin(), v.end());
auto it = upper_bound(v.begin(), v.end(), 2);
cout << it - v.begin() << endl;
it = upper_bound(v.begin(), v.end(), 3);
cout << it - v.begin() << endl;
return 0;
}
// 3 4
其他的一些操作
std::copy
简介:
把指定区间[first,last)
的元素复制到指定的容器内,并返回容器的最后一个复制元素的后一个迭代器。
template <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);
代码实例:
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v{2, 1, 3, 6, 5, 4, 9, 8, 7, 0};
vector<int>v1(v.size()); // 注意初始化容器的容量
copy(v.begin(), v.end(), v1.begin()); // 注意传入的都是迭代器
auto t = v1.size();
for(int i = 0; i < t; ++i) {
cout << v1[i] << " ";
}
cout << endl;
return 0;
}
std::swap
简介:
快速交换两个元素的值
template <class T> void swap (T& a, T& b);
for_each
简介:
泛型的for
操作,在迭代的同时,对迭代的对象进行有关的操作。返回函数指针或函数对象
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function fn);
实例:
#include <bits/stdc++.h>
using namespace std;
void myfun(int i) {
cout << i << " ";
}
int main() {
vector<int>v{2, 1, 3, 6, 5, 4, 9, 8, 7, 0};
for_each(v.begin(), v.end(), myfun);
cout << endl;
return 0;
}
std::reverse
简介:
容器范围[first,last)
的元素逆序。
template <class BidirectionalIterator>
void reverse (BidirectionalIterator first, BidirectionalIterator last);
std::getline
简介:
把输入流is
的元素读入str
中,delim
是终止字符,即遇到流中的第一个delim
就停止读入
istream& getline (istream& is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream& is, string& str);
istream& getline (istream&& is, string& str);