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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM