天天看点

c++STL通用容器 之 集合

set 、multiset都是集合类,差别在于set中部允许有重复元素,multiset中允许有重复元素。

常用函数

(1)构造函数

set(constPred&comp = Pred(),constA& al = A()); 创建空集合

set(constset& x); 拷贝构造函数

set(constvalue_type*first,constvalue_type*last,constPred&comp = Pred(),constA& al = A());

拷贝[first,last)之间元素构成新集合

multiset(constPred&comp = Pred(),constA& al = A()); 创建空集合

multiset(constmultiset&x); 拷贝构造函数

multiset(constvalue_type*first,constvalue_type*last,constPred&comp = Pred(),constA& al = A()); 

拷贝[first,last)之间元素构成新集合

(2)大小、判断空函数

intsize()const  ;返回容器元素个数

boolempty()const  ;判断容器是否空,若返回true,表明容器已空

(3)增加、删除函数

pair<iterator,bool>insert(constvalue_type&x); 插入元素x

iterator insert(iteratorit,constvalue_type&x); 在迭代指针it处,插入元素x

void insert(constvalue_type*first,constvalue_type*last);插入[first,last)间元素

iterator erase(iteratorit); 删除迭代指针it处元素

iterator erase(iteratorfirst, iterator last);删除[first,last)迭代指针间元素

size_typeerase(constKey& key);删除元素值等于key的元素

(4)遍历函数

iterator begin(); 返回首元素的迭带器指针

iterator end(); 返回尾元素后的迭带器指针,而不是尾元素的迭带器指针

reverse_iteratorrbegin();      返回尾元素的逆向迭带器指针,用于逆向遍历容器

reverse_iteratorrend(); 返回首元素前的逆向迭带器指针,用于逆向遍历容器

(5)操作函数

const_iteratorlower_bound(constKey& key);返回容器元素等于key迭代指针,否则返回end()

const_iteratorupper_bound(constKey& key);

intcount(constKey& key)const;返回容器中元素值等于key的元素个数

pair<const_iterator,const_iterator>equal_range(constKey& key) const;

  返回容器中元素值等于key的迭代指针[first,last)

const_iteratorfind(constKey& key)const;查找功能,返回元素值等于key迭代器指针

void swap(set&s); 交换单集合元素

void swap(multiset&s); 交换多集合元素

三种形成集合方法

#include <iostream>
#include <set>
using namespace std;
void display(multiset<int,greater<int> >&s)
{
    multiset<int>::iterator te=s.begin();
    while (te!=s.end())
    {
        cout<<*te++<<"\t";
    }
    cout<<endl;
}
int main()
{
    int a[]={5,3,9,3,7,2,9,3};
    multiset<int,greater<int> >myset;
    for(int i=0;i<sizeof(a)/sizeof(int);i++)
    {
        myset.insert(a[i]);
    }
    cout<<"通过函数insert(T t)添加集合:"<<endl;
    display(myset);
    
    cout<<"通过复制构造函数创建集合:"<<endl;
    multiset<int,greater<int> >myset2(myset);
    display(myset2);
    cout<<"通过构造函数创建集合:"<<endl;
    multiset<int,greater<int> >myset3(a,a+sizeof(a)/sizeof(int));
    display(myset3);
    return 0;
}
           

equal_range, pair, count, size用法举例

#include <iostream>
#include <set>
using namespace std;
int main()
{
    int a[]={5,3,9,3,7,2,9,3};
    set<int>myset(a,a+sizeof(a)/sizeof(int));
    multiset<int>mymultiset(a,a+sizeof(a)/sizeof(int));
    pair<set<int>::iterator,set<int>::iterator>rangeset;
    pair<multiset<int>::iterator,multiset<int>::iterator>rangesetmultiset;
    rangeset=myset.equal_range(3);
    rangesetmultiset=mymultiset.equal_range(3);
    long nCount=myset.count(3);
    long nMultiCount=mymultiset.count(3);
    set<int>::iterator te;
    cout<<"set(搜索值等于3的元素):";
    for(te=rangeset.first;te!=rangeset.second;te++)
    {
        cout<<*te<<"\t";
    }
    cout<<endl;
    cout<<"\t个数是:"<<nCount<<endl;
    cout<<"\t总元素个数是:"<<myset.size()<<endl;
    multiset<int>::iterator it;
    cout<<"multiset(搜索值等于3的元素):";
    for (it=rangesetmultiset.first;it!=rangesetmultiset.second;it++)
    {
        cout<<*it<<"\t";
    }
    cout<<endl;
    cout<<"\t个数是:"<<nMultiCount<<endl;
    cout<<"\t总个数是:"<<mymultiset.size()<<endl;
    return 0;
}
           

编一个集合类,包括并、交、差等主要功能,不允许有重复数据。并用学生类Student加以测试。 分析:很明显要用到set类,但set本身并没有两集合的并、交、差函数。因此从set类派生,增加并、交、差3个主要函数即可,集合类MySet及测试用到的Student类如下所示。

#include <iostream>
#include <string>
#include <set>
#include<iterator>
using namespace std;
class Student
{
private:
    string number;
    string name;
public:
    Student(string num,string na):number(num),name(na){}
    bool operator<(const Student &s)const
    {
        int mark=number.compare(s.number);
        return mark<0? true:false;
    }
    string GetNumber()
    {
        return number;
    }
    string GetName()
    {
        return name;
    }
};
ostream &operator<<(ostream &os,Student &s)
{
    os<<s.GetNumber()<<"\t"<<s.GetName()<<endl;
    return os;
}
template <class T,class Pred=less<T>,class A=allocator<T> >
class MySet:public set<T,Pred,A>
{
    
public:
    MySet(const T *first,const T *last):set<T>(first,last){}
    void Add(MySet &second) //两集合并
    {
        iterator te=second.begin();  //编译通不过???
        while(te != second.end())
        {
            insert(*te);
            te++;
        }
    }
    void Intersection(MySet &second)  //两集合交
    {
        set<T>mid;
        iterator te=this->begin();   //编译通不过???
        while(te != this->end())
        {
            if(second.find(*te) != second.end())
            {
                mid.insert(*te);
            }
            te++;
        }
        swap(mid);
    }
    void Difference(MySet &second)
    {
        set<T>mid;
        iterator te=this->begin();    //编译通不过???
        while(te!=this->end())
        {
            if(second.find(*te)==second.end())
            {
                mid.insert(*te);
            }
            te++;
        }
        swap(mid);
    }
    void show()
    {
        iterator te=this->begin();    //编译通不过???
        while(te!= this->end())
        {
            cout<<*te<<endl;
            te++;
        }
    }
};
int main()
{
    Student s[2]={{Student("1001","爱迪生")},{Student("1002","奥迪")}};
    Student t[3]={{Student("1003","奥迪的")},{Student("1004","潍坊")},{Student("1005","矮人国")}};
    MySet<Student>m1(s,s+2);
    MySet<Student>m2(t,t+3);
    cout<<"原始m1集合:"<<endl;
    m1.show();
    cout<<"原始m2集合:"<<endl;
    m2.show();
    
    cout<<"m1并m2为:"<<endl;
    m1.Add(m2);
    m1.show();
    cout<<"m1交m2为:"<<endl;
    m1.Intersection(m2);
    m1.show();
    cout<<"m1差m2为:"<<endl;
    m1.Difference(m2);
    m1.show();
    cout<<endl;
    return 0;
}