zoukankan      html  css  js  c++  java
  • C++集合基本操作

    multiset

    multiset是<set>库中一个非常有用的类型,可看成一个序列。插入删除都能够在O(logn)的时间内完成,并保证序列中的数是有序的,而且序列中可以存在重复的数。

    可以用列表初始化和insert建立。

        std::multiset<int> words1{ 1,2,2,3,4 };
        int x;
        while (cin >> x)words1.insert(x);
        for (int i : words1)cout << i << "  ";

    假如输入3,输出为:1  2  2  3  3  4 。

    inset还可以插入两个迭代器之间所有值。

        std::multiset<int> words1{ 1,2,3,4,5,6,7};
        vector<int> num = { 4,3,9,6 };
        words1.insert(num.begin(),num.end());

    可以根据元素的值或者迭代器位置删除元素

        std::multiset<int> words1{ 1,2,2,3,4 };
        words1.erase(2);

    输出:1  3  4 。所有的2都被删除。

        std::multiset<int> words1{ 1,2,2,3,4,5,7,7 };
        auto iter1 = words1.begin();
        auto iter2 = words1.end();
        iter1++; iter1++;
        iter2--;
        words1.erase(iter1,iter2);

    输出:1  2  7 。两个迭代器区间内(左闭右开)的值被删除

    由于multiset是有序的,所以要放入自定义类型,就需要定义比较类cmp。

    struct rec {
        int x, y;
    };
    struct cmp {
        bool operator()(const rec& a, const rec& b)  {
            return (a.x *a.y)<(b.x*b.y);
        }
    };
    
    int main(){
        multiset<rec, cmp>h;
        rec a, b, c, d;
        a = { 4,5 };
        b = { 3,7 };
        c = { 3,6 };
        d = { 1,19 };
        h = {a,b,c,d};
        for (rec i :h)cout << i.x << "  " << i.y << "  ";
    }

    结果会报错:

    错误 C3848 具有类型“const cmp”的表达式会丢失一些 const-volatile 限定符以调用“bool cmp::operator ()(const rec &,const rec &)” 

    如下修改后成功编译。参考了:https://www.cnblogs.com/qrlozte/p/4437418.html

    struct cmp {
        bool operator()(const rec& a, const rec& b) const {
            return (a.x *a.y)<(b.x*b.y);
        }
    };

    并集

        std::multiset<int> words1{ 1,2,2,3,4 };
        std::multiset<int> words2{ 1,2,3,3,3 }; 
        std::multiset<int> words3;
        std::set_union(std::begin(words1), std::end(words1), std::begin(words2), std::end(words2), std::inserter(words3, std::begin(words3)));
        for (int i : words3)cout << i << "  ";

    输出: 1  2  2  3  3  3  4  。输出并集中重复个数,为输入中重复个数的最大值。

    交集

    int iarr1[]={1,2,3,3,4,5,6,7,9};  
        int iarr2[]={1,4,3,9,10};  
        multiset<int> iset1(begin(iarr1),end(iarr1));  
        multiset<int> iset2(begin(iarr2),end(iarr2));  
        vector<int> ivec(20);      
        auto iter=set_intersection(iset1.begin(),iset1.end(),iset2.begin(),iset2.end(),ivec.begin());   //返回输出末尾的迭代器
        ivec.resize(iter-ivec.begin());//重新确定ivec大小  

    假如不重新确定大小,就会输出20个数。注意一开始初始化ivec时要给够足够大小,不然会out of range。

    其实直接对有序数组做交集都是可以的,没必要先转化为multiset。

    int iarr1[]={1,2,3,3,6,7,4,5};  
        int iarr2[]={1,4,3,10,9};  
        std::sort(begin(iarr1),end(iarr1));  
        std::sort(begin(iarr2),end(iarr2));  
        vector<int> ivec(10);    
        auto iter=set_intersection(begin(iarr1),end(iarr1),begin(iarr2),end(iarr2),ivec.begin());   //ivec =1 3 4 
        ivec.resize(iter-ivec.begin());//重新确定ivec大小  

    子集判断。用include函数,判断前两个迭代器之间的集合是否包括后两个迭代器之间的集合。

        std::multiset<int> words1{ 1,2,3,3,3,4,5,6};
        std::multiset<int> words2{ 1,2,3,3,3 }; 
        cout << std::boolalpha<< std::includes(words1.begin(),words1.end(),words2.begin(),words2.end() );//true
    
        std::multiset<int> words1{ 1,2,3,3,4,5,6};
        std::multiset<int> words2{ 1,2,3,3,3 }; 
        cout << std::boolalpha<< std::includes(words1.begin(),words1.end(),words2.begin(),words2.end() );//false
  • 相关阅读:
    bzoj 4451 : [Cerc2015]Frightful Formula FFT
    bzoj 3928: [Cerc2014] Outer space invaders
    HDU 5306 线段树
    bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形
    bzoj 4519: [Cqoi2016]不同的最小割 最小割树
    bzoj : 4504: K个串 区间修改主席树
    bzoj 4332:JSOI2012 分零食
    bzoj 2595 : [Wc2008]游览计划
    poj 3683 Priest John's Busiest Day
    bzoj 1823: [JSOI2010]满汉全席 && bzoj 2199 : [Usaco2011 Jan]奶牛议会 2-sat
  • 原文地址:https://www.cnblogs.com/zhangyangrui/p/12905771.html
Copyright © 2011-2022 走看看