ACM学习历程10——set集合容器

Set集合容器,是一种实现了平衡二叉树的数据结构,容器中的数据不能重复,即每个数据都是唯一的,而且容器中的数据页数不能直接修改的,因为修改后的数据很可能不在原来的数位上。Set容器的主要目的是快速检索数据元素,减速时采用中序遍历,可将容器内数据由小到大遍历处理。需要注意的是,关联容器的迭代器不支持it+n操作,仅支持it++

Set容器的定义和使用方法如下:

(一)Set容器的定义:

set<类型> 对象名; 如:set<int> s;  

set<类型,比较结构体> 对象名; 如:set<intmyComp> s; Set容器在插入时,默认情况下按从小到大的顺序存储,可以通过自定义比较结构体,按从大到小的顺序存储或者按照多个关键字序列插入。

(二)添加元素:

set<int> s;

s.insert(8);

s.insert(10);

s.insert(6);

s.insert(8); 重复元素不会插入

(三)遍历访问:

1)顺序遍历:

set<int> s;

set<int>::iterator it;

for(it=s.begin();it!=s.end();s++)

*it;

2)反序遍历:

set<int>::reverse_iterator it;

for(it=s.rbegin();it!=s.rend();s++)

*it;

(四)删除元素:

erase(迭代器)

erase(元素值)

erase(迭代器1,迭代器2)

clear(),清空容器,相当于删除所有的元素。

(五)查找元素:

find (元素),返回一个迭代器值。查找结果:找到了,返回指向该元素的迭代器;没找到,返回s.end();

(六)自定义比较函数:

1)当set中存储的数据,需要按自定义的规则进行比较大小时;

2)当set中存储的是自定义数据时,如结构体,类等。

第一种情况,元素类型不是结构体。

首先,定义比较结构体

struct myComp

{

bool operator() (const 类型 &a, const 类型 &b)

   {

……returna>b;

}

};

然后,定义set

set<类型,myComp> s

 

第二种情况,元素类型是结构体。

首先,在结构体中,增加“operator <”函数

struct 结构体

{

bool operator < (const 结构体类型 &a)

   {

……return(…);

}

};

然后,定义set

set<类型> s

Example:

#include<iostream>
#include<set>
using namespace std;
typedef struct non
{
    bool operator()(const int &a,const int &b)
    {
        if(a!=b)
            return a>b;
        else
            return a>b;
    }

} STU;

int main()
{
    set<int,STU> v;
    set<int,STU>::iterator p;
    v.insert(5);
    v.insert(4);
    v.insert(7);
    v.insert(2);
    v.insert(9);
    for(p=v.begin(); p!=v.end(); p++)
        cout<<*p<<' ';
    cout<<endl;
}
输出结果:9 7 5 4 2

#include<iostream>
#include<set>
#include<string>
using namespace std;
typedef struct non
{
    string name;
    float score;
    bool operator<(const non &a) const
    {
        return a.score<score;
    }
} STU;

int main()
{
    set<STU> v;
    STU s;
    s.name="Jack";
    s.score=80.5;
    v.insert(s);
    s.name="Nacy";
    s.score=60.5;
    v.insert(s);
    s.name="Tomi";
    s.score=20;
    v.insert(s);
    set<STU>::iterator p;
    for(p=v.begin(); p!=v.end(); p++)
    {
        cout<<(*p).name<<" : "<<(*p).score<<endl;
    }
    return 0;
}
输出结果:
Jack : 80.5
Nacy : 60.5
Tomi : 20

(七)考虑使用Set的情况:

1)排序,插入到容器内的数据是随机的,插入后,数据是有序的。

2)需要在容器内实现快速查找。

3)某一条件要求多个结果是相等的,此时可利用set中数据的唯一性。

 

应用举例一:

01串排序:将01串首先按长度排序,长度相同按1的个数排序,1的个数相同按ASCII码排序

输入:

10011111

00001101

1010101

1

0

1100

输出:

0

1

1100

1010101

00001101

10011111

测试数据通过文件读入:


#include<iostream>
#include<fstream>
#include<set>
#include<string>
#include<algorithm>
using namespace std;

struct Comp
{
    bool operator () (const string &s1,const string &s2)
    {
        if(s1.length()!=s2.length())
            return(s1.length()<s2.length());
        int c1=count(s1.begin(),s1.end(),'1');
        int c2=count(s2.begin(),s2.end(),'1');
        if(c1!=c2)
            return (c1<c2);
        else
            return(s1<s2);
    }
};
int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    set<string,Comp> s;
    string t;
    int n;
    while(fin>>t)
    {
        s.insert(t);
    }

    set<string,Comp>::iterator it;
    for(it=s.begin(); it!=s.end(); it++)
        fout<<*it<<endl;
    fin.close();
    fout.close();
    return 0;
}
输出结果:


 应用举例二:

输入若干个时间,对其进行排序,从小到大输出

输入:

3

12:59:30

1:20:40

1:20:30

输出:

1:20:30

1:20:40

12:59:30

 输入数据:


#include<iostream>
#include<fstream>
#include<set>
using namespace std;

struct time
{
    int hour;
    int minute;
    int second;
    bool operator < (const time &a)const
    {
        if(hour!=a.hour)
            return(hour<a.hour);
        else if(minute!=a.minute)
            return(minute<a.minute);
        else
            return(second<a.second);
    }
};
int main()
{
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    set<struct time> s;
    struct time t;
    int n;
    fin>>n;
    for(int i=0; i<n; i++)
    {
        fin>>t.hour;
        fin.get();
        fin>>t.minute;
        fin.get();
        fin>>t.second;
        s.insert(t);
    }

    set<struct time>::iterator it;
    for(it=s.begin(); it!=s.end(); it++)
        fout<<(*it).hour<<":"<<(*it).minute<<":"<<(*it).second<<endl;

    fin.close();
    fout.close();
    return 0;
}
输出结果:


Set容器其他操作方法可以参考下表,并查询相关的帮助文档:


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值