程序设计竞赛中常用的STL汇总

程序设计竞赛中常用的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);

迭代器:

  1. begin() 指向第一个元素
  2. end()指向最后一个元素的后一位,空的,没有任何元素!
  3. cbegin()常指针,指向第一个元素
  4. cend()常指针,位置同end()

容量:

  1. size()返回当前元素个数

  2. max_size()返回当前系统当前情况可以容纳某类型元素最多的个数(竞赛中一般用不到i)

  3. resize()重新分配元素个数

    void resize (size_type n);  // 更改元素个数
    void resize (size_type n, const value_type& val); // 更改元素个数,并指定值

    如果元素少于原先的,直接从尾部删除,此时指定val是无效的。如果多余原先的,不指定val默认新添加的为0,否则新添加的是val

  4. empty()是否为空判断,空返回true,否则返回false

元素访问

  1. operator[]同数组下标访问,返回元素的引用
  2. at()作用同operator[]
  3. front()返回第一个元素的引用
  4. back()返回最后一个元素的引用

基本操作

  1. assign()作用基本同构造函数,不过可以直接运行中调用,且不能列表初始化

  2. push_back(const T& val)或者push_back(T&&),把元素加入尾部

  3. pop_back()把尾部元素删除

  4. 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);
  6. swap交换两个有相同类型数据的vector

    void swap (vector& x);
  7. clear删除vector中所有的元素。

std::list

简介:

双向链表,不支持随机访问。

构造函数

vector的构造函数格式相同。

迭代器

vector

容量

vector

元素访问

  1. front()返回链首元素的引用
  2. back()返回链尾元素的引用

操作

  1. operator=给整个链表赋值

    list& operator= (const list& x);
    list& operator= (list&& x);
    list& operator= (initializer_list<value_type> il);
  2. assign()vector

  3. resize重新分配空间

    void resize (size_type n);
    void resize (size_type n, const value_type& val);
  4. eraser()删除指定位置元素

    iterator erase (const_iterator position);
    iterator erase (const_iterator first, const_iterator last);
  5. push_front表头插入元素

    void push_front (const value_type& val);
    void push_front (value_type&& val);
  6. pop_front删除表头元素

  7. push_back尾部插入元素

    void push_back (const value_type& val);
    void push_back (value_type&& val);
  8. pop_back删除尾部元素

  9. 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);
  10. eraser删除元素,解释参照vector

    iterator erase (const_iterator position);
    iterator erase (const_iterator first, const_iterator last);
  11. swap交换两个链表

    void swap (list& x);
  12. resize()重新分配空间,解释参照vector

    void resize (size_type n);
    void resize (size_type n, const value_type& val);
  13. clear清空表

新增操作

  1. 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;
    }
  3. 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;
    }
  4. 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);
  6. reverse链表顺序逆序

std::queue

简介:

数据结构中先入先出的队列,不允许随机访问。

构造函数:

不允许使用初始化列表,不允许使用区间复制。只能使用默认构造函数或者使用复制构造复制其他已有的队列。

成员函数:

  1. empty是否为空的判断
  2. push元素入队
  3. size()当前元素个数
  4. front()返回队首元素的引用
  5. back()返回队尾元素的引用
  6. pop()队尾元素出队
  7. swap()交换两个队列元素
std::deque

简介:

双端队列,实现方式与std::queue不同,构造方式和vector一样,允许随机访问,与vector相比,多了push_front pop_front两个函数。用到的机会较少,需要时查找标准库

std::stack

简介:

数据结构中的栈,先入后出。实现方式和std::queue类似,构造方式和std::queue相同。不允许随机访问。

成员函数:

  1. empty()判断是否为空
  2. size()返回当前元素个数
  3. top()返回栈顶元素的引用
  4. push()元素入栈
  5. 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";

容量:

  1. size()字符的个数

  2. length()字符的个数

  3. resize()重新分配空间

    void resize (size_t n);
    void resize (size_t n, char c);

    解释同std::vector

  4. clear()清空

  5. empty()判断是否为空

元素访问:

  1. operator[]随机访问,返回引用
  2. at()随机访问,返回引用
  3. front()第一个元素
  4. back()最后一个元素

一般操作

  1. operator=

    string& operator+= (const string& str); // 追加string
    string& operator+= (const char* s);      // 追加C风格的string
    string& operator+= (char c);            // 追加单个字符
    string& operator+= (initializer_list<char> il);// 追加初始化列表
  2. 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); // 追加初始化列表
  3. insert插入。功能太多,直接找标准库

  4. eraser删除

    string& erase (size_t pos = 0, size_t len = npos);
    iterator erase (const_iterator p);   
    iterator erase (const_iterator first, const_iterator last);
  5. replace替换操作,找标准库

  6. 还有其他的一些操作,但是在竞赛里几乎不用,在这里不再提了。

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::vectorCompare是比较函数,规则与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;
}

成员函数:

  1. empty()判断是否为空
  2. size()返回当前元素个数
  3. top()返回堆顶元素的常引用
  4. push()添加元素入堆
  5. pop()堆顶元素出队
  6. 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;
}

成员函数:

  1. 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);
  2. eraser()删除指定的元素或者区间:

    iterator  erase (const_iterator position); // 删除指定位置的元素,返回删除的位置
    size_type erase (const value_type& val);   // 删除键值为val的元素
    iterator  erase (const_iterator first, const_iterator last); // 删除指定的区间
  3. operator=集合之间的赋值

  4. 迭代器,参照std::vector

  5. clear清空所有的元素

  6. 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_boundupper_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

操作:

  1. empty()判断是否为空

  2. size()返回当前有序组的个数

  3. operator[]按下标访问

  4. 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); // 插入初始化列表
  5. eraser()删除指定元素:

    iterator  erase (const_iterator position);  // 按照位置删除
    size_type erase (const key_type& k);        // 按照键值删除
    iterator  erase (const_iterator first, const_iterator last); // 删除指定区间
  6. clear()清空字典

  7. swap()交换两个字典的元素

  8. find()寻找特定的值,按照键值查找,并返回位置,没找到返回std::map::end()

    iterator find (const key_type& k);
    const_iterator find (const key_type& k) const;
  9. count()返回具有特殊键值的元素的个数。由于std::map的键值是唯一的,因此返回值只能是1或者0.

  10. 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

操作:

  1. swap()直接交换两个二元组
  2. operator=直接赋值
  3. first返回第一个元素,不是函数,是关键字
  4. 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;
}

其他的一些操作

  1. operator[]获取指定位置的元素的引用,可以更改值
  2. count()返回1的个数,位置从右往左!!!!!
  3. size()返回长度
  4. test()测试某个位是否是1
  5. any()测试是否有1
  6. none()测试是否都是0
  7. flip()反转某个bit位,如果不添加参数,反转所有bit位(等效成取反)。位置从右往左
  8. reset()重置某个bit位,不添加参数默认全部重置为0。位置从右往左

哈希

由于哈希不被C++标准库支持,貌似在竞赛里也不能用了23333333. 需要的自己搜一下std::hash_setstd::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);

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值