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
原文地址:https://www.cnblogs.com/zhangyangrui/p/12905771.html