zoukankan      html  css  js  c++  java
  • C++课程学习笔记第九周(下):STL(下)

    前言:本文主要是根据MOOC网北大课程——《程序设计与算法(三):C++面向对象程序设计》内容整理归纳而来,整理的课程大纲详见 https://www.cnblogs.com/inchbyinch/p/12398921.html

    本文接着上一章,继续介绍了STL中关联容器、容器适配器和算法。

    1 关联容器

    1.1 multiset

    //multiset类模板
    template<class Key, class Pred = less<Key>, class A = allocator<Key> >
    class multiset { …… };
    

    Pred类型的变量决定了multiset中的元素,“一个比另一个小”是怎么定义的。multiset运行过程中,比较两个元素x,y的大小的做法,就是生成一个Pred类型的变量,假定为op,若表达式op(x,y) 返回值为true,则x比y小。由于less函数模板是通过<来比较的,因此默认情况下自己的类Key需要实现运算符<的重载。

    multiset的成员函数

    • iterator find(const T & val); 在容器中查找值为val的元素,返回其迭代器(x小于y和y小于x同时为false即为相等)。如果找不到,返回end()。
    • iterator insert(const T & val); 将val插入到容器中并返回其迭代器。
    • void insert(iterator first, iterator last); 将区间(前闭后开)插入容器。
    • int count(const T & val); 统计有多少个元素的值和val相等。
    • iterator lower_bound(const T & val); 查找一个最大的位置it,使得begin()到it(前闭后开)中所有的元素都比val小。
    • iterator upper_bound(const T & val); 查找一个最小的位置it,使得it到end()(前闭后开)中所有的元素都比val大。
    • pair<iterator,iterator> equal_range(const T & val); 同时求得lower_bound和upper_bound。
    • iterator erase(iterator it); 删除it指向的元素,返回其后面的元素的迭代器(Visual studio 2010上如此,但是在C++标准和Dev C++中,返回值不是这样),也可以删除指定值。
    //示例:multiset使用
    #include <iostream>
    #include <set> //使用multiset须包含此文件
    using namespace std;
    template <class T>
    void Print(T first, T last){ 
        for(;first != last; ++first) cout << * first << " ";
        cout << endl;
    }
    class A {
        int n;
    public:
        A(int n_ ) { n = n_; }
        friend bool operator < ( const A & a1, const A & a2 ) { return a1.n < a2.n; }
        friend ostream& operator<< ( ostream & o, const A & a2 ) { o << a2.n; return o; }
        friend class MyLess;
    };
    struct MyLess {
        bool operator()( const A & a1, const A & a2){ //按个位数比大小 
            return ( a1.n % 10 ) < (a2.n % 10); 
         }
    };
    typedef multiset<A> MSET1; //MSET1用 "<"比较大小
    typedef multiset<A, MyLess> MSET2; //MSET2用 MyLess::operator()比较大小
    
    int main(){
        const int SIZE = 6;
        A a[SIZE] = { 4,22,19,8,33,40 };
        MSET1 m1;
        m1.insert(a, a+SIZE);
        m1.insert(22);
        cout << "1) " << m1.count(22) << endl; //输出 1) 2
        cout << "2) "; Print(m1.begin(),m1.end()); //输出 2) 4 8 19 22 22 33 40
        //m1元素:4 8 19 22 22 33 40
        MSET1::iterator pp = m1.find(19);
        if( pp != m1.end() ) //条件为真说明找到
            cout << "found" << endl; //本行会被执行,输出 found
        cout << "3) "; cout << * m1.lower_bound(22) << ","
            <<* m1.upper_bound(22)<< endl; //输出 3) 22,33
        pp = m1.erase(m1.lower_bound(22), m1.upper_bound(22));
        //pp指向被删元素的下一个元素
        cout << "4) "; Print(m1.begin(),m1.end()); //输出 4) 4 8 19 33 40
        cout << "5) "; cout << * pp << endl; //输出 5) 33
        MSET2 m2; // m2里的元素按n的个位数从小到大排
        m2.insert(a,a+SIZE);
        cout << "6) "; Print(m2.begin(),m2.end()); //输出 6) 40 22 33 4 8 19
        return 0;
    }    
        
    

    1.2 set

    不允许重复元素。插入set中已有的元素时,则忽略插入,且返回的 pair< iter, bool >中bool为false。

    //set类模板
    template<class Key, class Pred = less<Key>, class A = allocator<Key> >
    class set { … }
    
    //示例
    #include <iostream>
    #include <set>
    using namespace std;
    
    int main() {
        typedef set<int>::iterator IT;
        int a[5] = { 3,4,6,1,2 };
        set<int> st(a, a+5); // st里是 1 2 3 4 6
        pair< IT, bool > result; //pair定义可见multimap一节
        result = st.insert(5); // st变成 1 2 3 4 5 6
        if( result.second ) //插入成功则输出被插入元素
            cout << * result.first << " inserted" << endl; //输出: 5 inserted
        if( st.insert(5).second ) 
            cout << * result.first << endl;
        else
            cout << *result.first << " already exists" << endl;//输出 5 already exists
        pair<IT,IT> bounds = st.equal_range(4);
        cout << * bounds.first << "," << * bounds.second ; //输出:4,5
        return 0;
    }
    

    1.3 multimap

    • map/multimap里放着的都是pair模版类的对象,且按first从小到大排序
    • multimap中的元素由<关键字,值>组成,每个元素是一个pair对象,关键字就是first成员变量,其类型是Key
    • multimap中允许多个元素的关键字相同。元素按照first成员变量从小到大排列,缺省情况下用 less< Key > 定义关键字的“小于”关系。
    //STL中pair模板
    template<class _T1, class _T2>
    struct pair{
        typedef _T1 first_type;
        typedef _T2 second_type;
        _T1 first;
        _T2 second;
        pair(): first(), second() { }
        pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { }
        template<class _U1, class _U2>
        pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) { }
    };
    //第三个构造函数用法示例:
    pair<int,int> p(pair<double,double>(5.5,4.6)); //p.first=5, p.second=4
    
    
    //multimap模板
    template<class Key, class T, class Pred = less<Key>, class A = allocator<T> >
    class multimap {
        …
        typedef pair<const Key, T> value_type;
        ……
    }; //Key代表关键字的类型
    
    
    //示例1:multimap用法
    #include <iostream>
    #include <map>
    using namespace std;
    
    int main() {
        typedef multimap<int,double,less<int> > mmid;
        mmid pairs;
        cout << "1) " << pairs.count(15) << endl;
        pairs.insert(mmid::value_type(15,2.7));//typedef pair<const Key, T> value_type;
        pairs.insert(mmid::value_type(15,99.3));
        cout << "2) " << pairs.count(15) << endl; //求关键字等于某值的元素个数 2
        pairs.insert(mmid::value_type(30,111.11));
        pairs.insert(mmid::value_type(10,22.22));
        pairs.insert(mmid::value_type(25,33.333));
        pairs.insert(mmid::value_type(20,9.3));
        for( mmid::const_iterator i = pairs.begin(); i != pairs.end(); i++ )
        cout << "(" << i->first << "," << i->second << ")" << ",";
        //(10,22.22),(15,2.7),(15,99.3),(20,9.3),(25,33.333),(30,111.11)
    }
    
    
    //示例2:学生成绩录入和查询系统
    //接受以下两种输入: Add name id score 或者 Query score
    //name是个字符串,中间没有空格,代表学生姓名。id是个整数,代表学号。score是个整数,表示分数。学号不会重复,分数和姓名都可能重复。两种输入交替出现。第一种输入表示要添加一个学生的信息。第二种输入表示要查询,碰到这种输入,就输出已有记录中分数比score低的最高分获得者的姓名、学号和分数。如果有多个学生都满足条件,就输出学号最大的那个学生的信息。如果找不到满足条件的学生,则输出“Nobody”
    //输入样例:
    Add Jack 12 78
    Query 78
    Query 81
    Add Percy 9 81
    Add Marry 8 81
    Query 82
    Add Tom 11 79
    Query 80
    Query 81
    输出结果样例:
    Nobody
    Jack 12 78
    Percy 9 81
    Tom 11 79
    Tom 11 79
    
    //实现代码
    struct CStudent{ //定义学生信息的类
        string name;
        int id;
        int score;
    };
    typedef multimap<int, CStudent> mmap;
    
    int main(){
        string s;
        CStudent stu;
        int temp;
        mmap score_os; //定义一个成绩系统
        mmap::iterator p;
    
        while(cin >> s){ //读入指令
            if(s == "Add"){
                cin >> stu.name >> stu.id >> stu.score;
                score_os.insert(mmap::value_type(stu.score, stu));
                //mp.insert(make_pair(stu.score,stu)); 也可以
            }else if(s == "Query"){
                cin >> temp;
                p = score_os.lower_bound(temp);
                if(score_os.empty() || p == score_os.begin()) 
                    //若字典为空或全部都不小于temp
                    cout << "Nobody" << endl;
                else{ //找到小于查询值的分数
                    --p; //将指针前移一位
                    stu = p->second; //获取所求的学生信息
                    //若指针有效且分数一样,则持续前移以查找
                    while(--p!=score_os.begin() && p->first==stu.score){ 
                        if(p->second.id > stu.id)  stu = p->second;
                     }
                    //刚才跳出循环可能是因为移动到开头了,需要单独处理
                    if(p==score_os.begin() && p->first==stu.score){ 
                        if(p->second.id > stu.id)  stu = p->second;
                     }
                    cout << stu.name << " " << stu.id << " " << stu.score << endl;
                 }
            }else{
                cout << "输入有误,重新输入" << endl;
            }
        }
    
        return 0;
    }
    

    1.4 map

    • map 中的元素都是pair模板类对象。与multimap的唯一区别就是map中关键字(first成员变量)各不相同。元素按照关键字从小到大排列,缺省情况下用 less< Key >,即“<” 定义“小于”。
    • 若pairs为map模版类的对象,pairs[key]返回对关键字等于key的元素的值(second成员变量)的引用。若没有关键字为key的元素,则会往pairs里插入一个关键字为key的元素,其值用无参构造函数初始化,并返回其值的引用。
    //模板
    template<class Key, class T, class Pred = less<Key>, class A = allocator<T> >
    class map {
        …
        typedef pair<const Key, T> value_type;
        …
    };
    
    //示例
    template <class Key,class Value>
    ostream & operator <<( ostream & o, const pair<Key,Value> & p){
        o << "(" << p.first << "," << p.second << ")";
        return o;
    }
    
    int main() {
        typedef map<int, double, less<int> > mmid;
        mmid pairs;
        cout << "1) " << pairs.count(15) << endl; //1) 0
        pairs.insert(mmid::value_type(15, 2.7));
        pairs.insert(make_pair(15,99.3)); //make_pair生成一个pair对象
        cout << "2) " << pairs.count(15) << endl; //2) 1
        pairs.insert(mmid::value_type(20,9.3));
        mmid::iterator i;
        cout << "3) ";
        for( i = pairs.begin(); i != pairs.end();i ++ ) 
            cout << * i << ",";   //3) (15,2.7),(20,9.3),
        cout << endl;
        cout << "4) ";
        int n = pairs[40];//如果没有关键字为40的元素,则插入一个
        for( i = pairs.begin(); i != pairs.end();i ++ )
            cout << * i << ",";  //4) (15,2.7),(20,9.3),(40,0),
        cout << endl;
        cout << "5) ";
        pairs[15] = 6.28; //把关键字为15的元素值改成6.28
        for( i = pairs.begin(); i != pairs.end();i ++ )
            cout << * i << ",";  //5) (15,6.28),(20,9.3),(40,0),
    }
    

    注意:C++11中提供了unordered_map和unordered_multimap,实现方式是哈希表,更好用。

    2 容器适配器

    • 由于容器适配器不支持迭代器,故STL中很多算法都不适用于适配器。
    • 均有常用函数:empty、size。
    //stack类模板
    template<class T, class Cont = deque<T> >
    class stack{ … };
    
    //queue类模板
    template<class T, class Cont = deque<T> >
    class queue{ … };
    
    //priority_queue类模板
    template <class T, class Container = vector<T>, class Compare = less<T> >
    class priority_queue{ … };
    

    2.1 stack

    • 可用 vector, list, deque来实现。缺省情况下,用deque实现。用 vector和deque实现,比用list实现性能好。
    • stack 有主要操作:push、pop、top。

    2.2 queue

    • 和stack 基本类似,可以用 list和deque实现。缺省情况下用deque实现。
    • queue 有主要操作:push、pop、front、back。(注意此pop是弹出头元素,与stack不同;front返回头元素引用)

    2.3 priority_queue

    • 和queue类似,可以用vector和deque实现。缺省情况下用vector实现。
    • priority_queue 通常用堆排序技术实现,保证最大的元素总是在最前面。即执行pop操作时,删除的是最大的元素;执行top操作时,返回的是最大元素的常引用。默认的元素比较器是less< T >。
    • priority_queue 中top函数返回的是const型引用,如果是非const则可能有被修改成非最大值的风险。
    int main(){
        priority_queue<double> pq1;
        pq1.push(3.2); pq1.push(9.8); pq1.push(9.8); pq1.push(5.4);
        while( !pq1.empty() ) {
            cout << pq1.top() << " ";
            pq1.pop();
         } //上面输出 9.8 9.8 5.4 3.2
        cout << endl;
        priority_queue<double, vector<double>, greater<double> > pq2;
        pq2.push(3.2); pq2.push(9.8); pq2.push(9.8); pq2.push(5.4);
        while( !pq2.empty() ) {
            cout << pq2.top() << " ";
            pq2.pop();
         } //上面输出 3.2 5.4 9.8 9.8
        return 0;
    }    
    

    3 算法

    STL提供能在各种容器中通用的算法(大约有80多种),如插入、删除、查找、排序等。STL算法部分主要由头文件< algorithm >, < numeric >, < functional >组成。要使用 STL中的算法函数必须包含头文件< algorithm >,对于数值算法须包含< numeric >,< functional >中则定义了一些模板类,用来声明函数对象。STL中绝大部分传给函数模板的操作pred都是函数对象(其实也可以是函数指针或函数名。)

    算法就是一个个函数模板,算法通过迭代器来操纵容器中的元素。许多算法可以对容器中的一个局部区间进行操作,因此需要两个参数,一个是起始元素的迭代器,一个是终止元素的后面一个元素的迭代器,比如排序和查找。有的算法返回一个迭代器。比如 find() 算法,在容器中查找一个元素,并返回一个指向该元素的迭代器。算法可以处理容器,也可以处理普通数组。

    大多重载的算法都是有两个版本的,其中一个是用“==”判断元素是否相等,或用“<”来比较大小;而另一个版本多出来一个类型参数“Pred”,以及函数形参“Pred op”,该版本通过表达式“op(x,y)”的返回值是ture还是false,来判断x是否“等于”y,或者x是否“小于”y。

    STL中的算法大致可以分为以下七类:

    • 1.不变序列算法
    • 2.变值算法
    • 3.删除算法
    • 4.变序算法
    • 5.排序算法
    • 6.有序区间算法
    • 7.数值算法

    3.1 不变值算法

    此类算法不会修改算法所作用的容器或对象,适用于所有容器。它们的时间复杂度都是O(n)的。

    最常用:

    • min 求两个对象中较小的(可自定义比较器)
    • max 求两个对象中较大的(可自定义比较器)
    • min_element 求区间中的最小值(可自定义比较器)
    • max_element 求区间中的最大值(可自定义比较器)
    • for_each 对区间中的每个元素都做某种操作(不改变原值)
    • count 计算区间中等于某值的元素个数
    • count_if 计算区间中符合某种条件的元素个数
    • find 在区间中查找等于某值的元素
    • find_if 在区间中查找符合某条件的元素

    其他:

    • find_end 在区间中查找另一个区间最后一次出现的位置,类似查找子序列(可自定义比较器)
    • find_first_of 在区间中查找第一个出现在另一个区间中的元素 (可自定义比较器)
    • adjacent_find 在区间中寻找第一次出现连续两个相等元素的位置(可自定义比较器)
    • search 在区间中查找另一个区间第一次出现的位置(可自定义比较器)
    • search_n 在区间中查找第一次出现等于某值的连续n个元素(可自定义比较器)
    • equal 判断两区间对应元素是否相等(可自定义比较器)
    • mismatch 逐个比较两个区间的元素,返回第一次发生不相等的两个元素的位置(可自定义比较器)
    • lexicographical_compare 按字典序比较两个区间的大小(可自定义比较器)

    3.2 变值算法

    最常用:

    • for_each 对区间中每一个元素进行某种操作,实现:逐个元素op(elem)。
    • copy 复制一个区间内容至另一处
    • copy_backward 从后往前复制区间内容至别处(适用于源区间和目标区间有重叠的情况)
    • transform 将区间元素进行某种操作后拷贝到别处(两种模板,可以进行一元操作或二元操作),实现:逐个元素op(elem)后赋给目标区间。注意:操作本身不改变elem值,但是可以原地赋给elem,效果就是原地进行函数变换。

    其他:

    • swap_ranges 交换两个区间内容,实现:逐个元素sawp。
    • fill 将目标值逐个赋给区间元素
    • fill_n 用目标值替换区间中的n个元素,和fill的区别是用个数n代替尾迭代器。
    • generate 用某个函数调用结果填充区间,常用于随机数生成。
    • generate_n 用某个函数调用结果替换区间中的n个元素。
    • replace 将区间中的某个值替换为另一个值
    • replace_if 将区间中符合某种条件的值替换成另一个值,实现:若pred(elem)==true,则替换。
    • replace_copy 将一个区间拷贝到另一个区间,拷贝时某个值要换成新值拷过去
    • replace_copy_if 将一个区间拷贝到另一个区间,拷贝时符合某条件的值要换成新值拷过去
    #include <vector>
    #include <iostream>
    #include <numeric>
    #include <list>
    #include <algorithm>
    #include <iterator>
    using namespace std;
    class CLessThen9 {
    public:
        bool operator()( int n) { return n < 9; }
    };
    void outputSquare(int value ) { cout << value * value << " "; }
    int calculateCube(int value) { return value * value * value; }
    
    int main() {
        const int SIZE = 10;
        int a1[] = { 1,2,3,4,5,6,7,8,9,10};
        int a2[] = { 100,2,8,1,50,3,8,9,10,2 };
        vector<int> v(a1, a1+SIZE);
        ostream_iterator<int> output(cout," "); //注意用法
        random_shuffle(v.begin(), v.end());
        cout << endl << "1) ";
        copy( v.begin(), v.end(), output);
        copy( a2, a2+SIZE, v.begin());
        cout << endl << "2)";
        cout << count(v.begin(), v.end(), 8);
        cout << endl << "3)";
        cout << count_if(v.begin(), v.end(), CLessThen9());
        cout << endl << "4)";
        cout << * (min_element(v.begin(), v.end()));
        cout << endl << "5)";
        cout << * (max_element(v.begin(), v.end()));
        cout << endl << "6) ";
        cout << accumulate(v.begin(), v.end(), 0);//求和
        cout << endl << "7) ";
        for_each(v.begin(), v.end(), outputSquare);
        vector<int> cubes(SIZE);
        transform(a1, a1+SIZE, cubes.begin(), calculateCube);
        cout << endl << "8) ";
        copy( cubes.begin(), cubes.end(), output);
    }
    

    3.3 删除算法

    删除算法会删除一个容器里的某些元素。这里所说的“删除”,并不会使容器里的元素减少,其工作过程是:将所有应该被删除的元素看做空位子,然后用留下的元素从后往前移,依次去填空位子。元素往前移后,它原来的位置也就算是空位子,也应由后面的留下的元素来填上。最后,没有被填上的空位子,维持其原来的值不变。删除算法不应作用于关联容器。

    • unique 删除区间中连续相等的元素,只留下一个(可自定义比较器),返回删除后的区间的最后一个元素的后一个迭代器,可以用其与begin比较来获取有效长度。
    • unique_copy 拷贝区间到另一个区间。连续相等的元素,只拷贝第一个到目标区间 (可自定义比较器)
    • remove 删除区间中等于某个值的元素
    • remove_if 删除区间中满足某种条件的元素
    • remove_copy 拷贝区间到另一个区间。等于某个值的元素不拷贝
    • remove_copy_if 拷贝区间到另一个区间。符合某种条件的元素不拷贝
    int main(){
        int a[5] = { 1,2,3,2,5};
        int b[6] = { 1,2,3,2,5,6};
        ostream_iterator<int> oit(cout,",");
        int * p = remove(a,a+5,2);
        cout << "1) "; copy(a,a+5,oit); cout << endl;
        //输出 1) 1,3,5,2,5,
        cout << "2) " << p - a << endl; //输出 2) 3
        vector<int> v(b,b+6);
        remove(v.begin(),v.end(),2);
        cout << "3) ";copy(v.begin(),v.end(),oit);cout << endl;
        //输出 3) 1,3,5,6,5,6,
        cout << "4) "; cout << v.size() << endl;
        //v中的元素没有减少,输出 4) 6
        return 0;
    }
    

    3.4 变序算法

    变序算法改变容器中元素的顺序,但是不改变元素的值。变序算法不适用于关联容器。此类算法复杂度都是O(n)的。

    • reverse 颠倒区间的前后次序
    • reverse_copy 把一个区间颠倒后的结果拷贝到另一个区间,源区间不变
    • random_shuffle 随机打乱区间内元素的顺序,适用于能随机访问的容器。用之前要初始化伪随机数种子: srand(unsigned(time(NULL))); //#include < ctime >
    • next_permutation 将区间改为下一个排列(可自定义比较器)
    • prev_permutation 将区间改为上一个排列(可自定义比较器)
    • partition 把区间内满足某个条件的元素移到前面,不满足该条件的移到后面
    • stable_patition 把区间内满足某个条件的元素移到前面,不满足该条件的移到后面。而且对这两部分元素,分别保持它们原来的先后次序不变
    • rotate 将区间进行循环左移
    • rotate_copy 将区间以首尾相接的形式进行旋转后的结果拷贝到另一个区间,源区间不变

    3.5 排序算法

    • sort 将区间从小到大排序(可自定义比较器)。
    • stable_sort 将区间从小到大排序,并保持相等元素间的相对次序(可自定义比较器)。
    • partial_sort 对区间部分排序,直到最小的n个元素就位(可自定义比较器),后面顺序不管。
    • partial_sort_copy 将区间前n个元素的排序结果拷贝到别处。源区间不变(可自定义比较器)。
    • nth_element 对区间部分排序,使得第n小的元素(n从0开始算)就位,而且比它小的都在它前面,比它大的都在它后面(可自定义比较器)。
    • make_heap 使区间成为一个“堆”(可自定义比较器),实现:建堆。
    • push_heap 将元素加入一个是“堆”区间(可自定义比较器),实现:在之前添加一个元素的基础上,将其上浮。
    • pop_heap 从 “堆”区间删除堆顶元素(可自定义比较器),实现:堆顶和最后一个元素互换后再下滤,容器大小不变。
    • sort_heap 将一个“堆”区间进行排序,排序结束后,该区间就是普通的有序区间,不再是 “堆”了(可自定义比较器)
    //示例:堆排序的用法(官网)
    int main () {
        int myints[] = {10,20,30,5,15};
        std::vector<int> v(myints, myints+5);
        std::make_heap (v.begin(), v.end());
        std::cout << "initial max heap   : " << v.front() << '
    ';
        
        std::pop_heap (v.begin(), v.end()); v.pop_back(); //注意pop_heap之后要手动弹出
        std::cout << "max heap after pop : " << v.front() << '
    ';
        v.push_back(99); std::push_heap (v.begin(), v.end()); //注意这两个联用
        std::cout << "max heap after push: " << v.front() << '
    ';
        std::sort_heap (v.begin(), v.end());
        
        std::cout << "final sorted range :";
        for (unsigned i=0; i<v.size(); i++)
            std::cout << ' ' << v[i];
        std::cout << endl;
        return 0;
    }
    

    注意:

    • 最常用的是sort。sort实际上是快速排序,平均性能最优;但是最坏的情况下,性能可能非常差。如果要保证“最坏情况下”的性能,那么可以使用stable_sort,内部采用归并,用法同sort。
    • 排序算法需要随机访问迭代器的支持,因而不适用于关联容器和list(list可用list::sort)。
    • 堆排序中,在make_heap之后调用push_heap和pop_heap均能自动调整以保持堆的特性;但是pop_heap之后需要手动弹出最后一个废值,push_heap之前需要将值添加进容器中。

    3.6 有序区间算法

    有序区间算法要求所操作的区间是已经从小到大排好序的,而且需要随机访问迭代器的支持。所以有序区间算法不能用于关联容器和list。

    • binary_search 判断区间中是否包含某个元素,实现:检查x<y是否为true。
    • includes 判断是否一个区间中的每个元素,都在另一个区间中(不要求连续)。
    • lower_bound 查找最后一个不小于某值的元素的位置。
    • upper_bound 查找第一个大于某值的元素的位置。
    • equal_range 同时获取lower_bound和upper_bound。
    • merge 合并两个有序区间到第三个区间。
    • inplace_merge 将两个连续的有序区间原地合并为一个有序区间
    • set_union 将两个有序区间的并拷贝到第三个区间,若某个元素e在第一区间里出现n1次,在第二区间里出现n2次,则该元素在目标区间里出现max(n1,n2)次。
    • set_intersection 将两个有序区间的交拷贝到第三个区间,若某个元素e在第一区间里出现n1次,在第二区间里出现n2次,则该元素在目标区间里出现min(n1,n2)次。
    • set_difference 将两个有序区间的差拷贝到第三个区间,若有多个相同元素不在第二区间,则均拷贝到第三区间。
    • set_symmetric_difference 将两个有序区间的对称差(即异或)拷贝到第三个区间

    3.7 数值算法

    主要针对一个类

    //类模板
    template<size_t N>  
    class bitset{
        …
    };
    //实际使用的时候,N是个整型常数,如bitset<40> bst
    //bst是一个由40位组成的对象,用bitset的函数可以方便地访问任何一位。
    
    bitset<N>& operator&=(const bitset<N>& rhs);
    bitset<N>& operator|=(const bitset<N>& rhs);
    bitset<N>& operator^=(const bitset<N>& rhs);
    bitset<N>& operator<<=(size_t num);
    bitset<N>& operator>>=(size_t num);
    bitset<N>& set(); //全部设成1
    bitset<N>& set(size_t pos, bool val = true); //设置某位
    bitset<N>& reset(); //全部设成0
    bitset<N>& reset(size_t pos); //某位设成0
    bitset<N>& flip(); //全部翻转
    bitset<N>& flip(size_t pos); //翻转某位
    
    reference operator[](size_t pos); //返回对某位的引用
    bool operator[](size_t pos) const; //判断某位是否为1
    reference at(size_t pos);
    bool at(size_t pos) const;
    unsigned long to_ulong() const; //转换成整数
    string to_string() const; //转换成字符串
    size_t count() const; //计算1的个数
    size_t size() const;
    bool operator==(const bitset<N>& rhs) const;
    bool operator!=(const bitset<N>& rhs) const;
    
    bool test(size_t pos) const; //测试某位是否为 1
    bool any() const; //是否有某位为1
    bool none() const; //是否全部为0
    bitset<N> operator<<(size_t pos) const;
    bitset<N> operator>>(size_t pos) const;
    bitset<N> operator~();
    static const size_t bitset_size = N;
    //注意:第0位在最右边
    
  • 相关阅读:
    什么是反射、javassist和asm(java动态编程)
    commons-codec
    commons-httpcomponents
    Servlet
    commons-compress(apache压缩工具包)
    java.io类
    JAVA的Class类
    Linux 命令行
    maven编译或者打包web项目显示“软件包 javax.servlet.http 不存在"
    有时候eclipse 导入maven项目 启动的时候回出现这样一个问题
  • 原文地址:https://www.cnblogs.com/inchbyinch/p/12398701.html
Copyright © 2011-2022 走看看