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是插入元素的个数
5. 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的元素
2. 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的迭代器移动。
5. 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
4. clear()清空
5. 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()
7. count()返回具有特定值元素的个数,因为std::set的元素键值是唯一的,所以只能返回1或者0
8. lower_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
N\log_2M
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;