STL之set(唯一且有顺序)
set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,
在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。
方法 用法
插入删除
insert(value) 向集合中插入一个元素
erase() 擦除元素中的一个或者一段元素
clear() 清除集合中的元素
查找
find() 查找value的值,返回下标位置,否则,返回最后一个元素后面一个位置(即迭代器的end)
容量
empty() 判断集合是否为空
size() 返回集合中的元素个数
max_size() 返回集合的最大容量
迭代器
begin() 返回开头的迭代器
end() 返回结尾的迭代器
rbegin() 反向遍历的首个位置迭代器
rend() 反向遍历的最后位置的迭代器
1 #include<iostream> 2 #include<set> 3 using namespace std; 4 int main() 5 { 6 set<int> s; 7 s.insert(1); 8 s.insert(2);//将key_value插入到set中 9 s.insert(3); 10 s.insert(1); 11 s.insert(4); 12 s.insert(6); 13 cout<<"set的size值为:"<<s.size()<<endl;//输s.size()出该set集合中的元素个数 14 cout<<"set的maxsize的值为:"<<s.max_size()<<endl;//max_size()输出地址 15 cout<<"set中的第一个元素是:"<<*s.begin()<<endl;//begin()输出最小的元素 16 cout<<"set中的最后一个元素是:"<<*s.end()<<endl;//end()输出最大的元素 17 cout<<"set中的是否出现过该元素是:"<<s.count(1)<<endl;//s.count(1)可以判断是否出现过该元素,出现为1,未出现为0 18 //equal_range()分别表示第一个大于或等于给定元素和第一个大于元素 19 pair<set<int>::const_iterator,set<int>::const_iterator> pr; 20 pr = s.equal_range(2); 21 cout<<"第一个大于等于 2 的数是 :"<<*pr.first<<endl; 22 cout<<"第一个大于 2的数是 : "<<*pr.second<<endl; 23 s.clear();//清空集合 24 if(s.empty())//判断集合是否为空 25 { 26 cout<<"set为空!!!"<<endl; 27 } 28 cout<<"set的size值为:"<<s.size()<<endl; 29 cout<<"set的maxsize的值为:"<<s.max_size()<<endl; 30 31 int a[] = {1,2,3};//建立set集合二 32 set<int> s2(a,a+3); 33 set<int>::iterator iter; 34 //find(),返回给定值值得定位器,如果没找到则返回end()。 35 if((iter = s2.find(2)) != s2.end()) //如果该数存在则会输出括号里的信息 36 { 37 cout<<"测试"<<*iter<<endl; 38 } 39 int b[]={9,8,7}; 40 s2.insert(b,b+3);//将定位器first到second之间的元素插入到set中 41 cout<<"set的size值为:"<<s2.size()<<endl;//返回s2中的元素个数 42 cout<<*s2.lower_bound(8)<<endl;//lower_bound(8)返回第一个大于等于key_value的定位器 43 cout<<*s2.upper_bound(8)<<endl; //upper_bound(8)返回最后一个大于等于key_value的定位器 44 }
uva 10815代码:
#include<iostream> #include<set> #include<string.h> #include<sstream> using namespace std; int main() { set<string>s; string h,buf; while(cin>>h) { for(int i=0;i<h.length();i++) { if(isalpha(h[i])) //判断一个字符是否为字母 h[i]=tolower(h[i]); else h[i]=' '; } stringstream ss(h);//定义了一个字符串流,并用一个字符串初始化 while(ss>>buf)//将buf读出到ss s.insert(buf); } //输出时需要运用迭代器 set<string>::iterator it; for(it=s.begin();it!=s.end();it++) cout<<(*it)<<"\n"; return 0; }
代码解析:
#include<iostream> #include<set> #include<string> #include<sstream> using namespace std; int main() { string s,buf; set<string> str; while(cin>>s) { for(int i=0;i<s.length();i++) { if(isalpha(s[i]))//将字母统一为小写,非字母的设为空格到时候便于忽略 s[i]=tolower(s[i]); else s[i]=' '; } stringstream ss(s);//设一个字符串流,用s来初始化 while(ss>>buf)//由于ss中可能有空格,这个就是以空格为界限 循环输入到buf(buf是不含空格的字符串(即单词))中 str.insert(buf); } for(set<string>::iterator it=str.begin();it!=str.end();it++) cout<<*it<<endl; getchar(); }
定义比较函数 例题:
typedef struct mycmp //自定义比较函数
{
bool operator()(const int &a,const int &b)
{
return a>b;
}
};
#include<iostream> #include<set> #include<string.h> #include<sstream> using namespace std; typedef struct mycmp //自定义比较函数 { bool operator()(const int &a,const int &b) { return a>b;//改变这里的>号改变顺序大小 } }; int main() { set<int,mycmp>s; s.insert(2); s.insert(7); s.insert(2); for(int i=10;i<14;i++)//顺序输入值 s.insert(i); cout<<"顺序输出:"<<endl; set<int>::iterator it; for(it=s.begin();it!=s.end();it++) cout<<*it<<" "; cout<<endl<<"反序输出:"<<endl; set<int>::reverse_iterator reit; for(reit=s.rbegin();reit!=s.rend();reit++) cout<<*reit<<" "; return 0; }
定义数据类型 结构体例题:
typedef struct mycmp
{
string name;
float score;
bool operator<(const mycmp &a)const//自定义比较函数
{
return a.score<score;//可更改这处的>而更改输出顺序
}
};
#include<iostream> #include<set> #include<string.h> #include<sstream> using namespace std; typedef struct mycmp { string name; float score; bool operator<(const mycmp &a)const//自定义比较函数 { return a.score<score;//可更改这处的>而更改输出顺序 } }; int main() { set<mycmp> v; mycmp 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<mycmp>::iterator p; for(p=v.begin(); p!=v.end(); p++) { cout<<(*p).name<<" : "<<(*p).score<<endl; } return 0; }
输出结果:(按crtl+z+alt)
Jack : 80.5
Nacy : 60.5
Tomi : 20
例题一:01串排序:将01串首先按长度排序,长度相同按1的个数排序,1的个数相同按ASCII码排序
输入:
10011111
00001101
1010101
1
0
1100
解题想法:使用set自定义比较函数,先看字符串长度,长度从小到大,如果长度相同,比较1的个数,我们这里用#include<algorithm>中的count(s1.begin(),s1.end(),'1')来计算1的个数,如果1的个数相同,按ascii码排序,个数不同,按个数大小排序
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);
}
};
#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() { set<string,Comp> s; string t; int n; while(cin>>t) { s.insert(t); } set<string,Comp>::iterator it; for(it=s.begin(); it!=s.end(); it++) cout<<*it<<endl; return 0; }
例题二:输入若干个时间,对其进行排序,从小到大输出
解题思路:定义自定义struct数据类型
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);
}
};
输入:
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() { set<struct time> s; struct time t; int n; cin>>n; for(int i=0; i<n; i++) { cin>>t.hour; cin.get(); cin>>t.minute; cin.get(); cin>>t.second; s.insert(t); } set<struct time>::iterator it; for(it=s.begin(); it!=s.end(); it++) cout<<(*it).hour<<":"<<(*it).minute<<":"<<(*it).second<<endl; return 0; }