【STL-set】set的使用 _STL自学笔记
来源:互联网 发布:http。默认端口 编辑:程序博客网 时间:2024/05/22 04:50
前言
啊啊啊,我还真是喜欢STL呢,明知道不能过度依赖它,但是就觉得好好用啊好方便啊怎么办……
啃饼干啃STL,今天又啃了一个set。
set是一个很棒的数据结构,度娘说:
“STL 对这个序列可以进行查找,插入删除序列中的任意一个元素,而完成这些操作的时间同这个序列中元素个数的对数成比例关系,并且当游标指向一个已删除的元素时,删除操作无效。而一个经过更正的和更加实际的定义应该是:一个集合(set)是一个容器,它其中所包含的元素的值是唯一的。这在收集一个数据的具体值的时候是有用的。集合中的元素按一定的顺序排列,并被作为集合中的实例。一个集合通过一个链表来组织,在插入操作和删除操作上比向量(vector)快,但查找或添加末尾的元素时会有些慢。具体实现采用了红黑树的平衡二叉树的数据结构。”
然后又有如下解释:
叫人如何不动心?于是来学学看了~
鉴于本人学习STL的方法是先拼命看啊看啊看,然后再敲啊敲啊敲,所以还是从SourceCode来看看比较符合我的胃口——
代码理解
set的初始化
首先是裸set模板,用int的太没诚意了,用个<string,int>型的结构体吧~
#include<set>#include<iostream>#include<algorithm>using namespace std;struct Info { string name; double score; bool operator < (const Info &a) const // Custom cmp_Rule { //Desc:< Asc:> return a.score < score; } }; int main(){set<Info> s; Info info; info.name = "Jack"; info.score = 80; s.insert(info); info.name = "Tom"; info.score = 99; s.insert(info); info.name = "Steven"; info.score = 60; s.insert(info); s.erase(s.find(info)); set<Info>::iterator it; for(it = s.begin(); it != s.end(); it++) cout << (*it).name << " : " << (*it).score << endl; return 0;}/* 运行结果: Tom : 99 Jack : 80 */可见set会自动维护其中元素的顺序,可以通过重载操作符的方式自定义排序的规则,
此外,erase删除某个元素时需要传参指向这个被删除的元素的迭代器;寻找是否存在某个元素,如果存在则获取其迭代位置的迭代器则使用find()函数。
说到erase,也可以传入两个参数作为前后指针删除其中的元素,代码如下:
// set::lower_bound/upper_bound#include <iostream>#include <set>int main (){ std::set<int> myset; std::set<int>::iterator itlow,itup; for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90 itlow=myset.lower_bound (30); // ^ itup=myset.upper_bound (60); // ^ myset.erase(itlow,itup); // 10 20 70 80 90 std::cout << "myset contains:"; for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0;}
关于等号的操作符重载
// assignment operator with sets#include <iostream>#include <set>int main (){ int myints[]={ 12,82,37,64,15 }; std::set<int> first (myints,myints+5); // set with 5 ints std::set<int> second; // empty set second = first; // now second contains the 5 ints first = std::set<int>(); // and first is empty std::cout << "Size of first: " << int (first.size()) << '\n'; std::cout << "Size of second: " << int (second.size()) << '\n'; return 0;}
如果只是像上述一样把first和second交换包含元素的话,其实swap也就够了:
// swap sets#include <iostream>#include <set>main (){ int myints[]={12,75,10,32,20,25}; std::set<int> first (myints,myints+3); // 10,12,75 std::set<int> second (myints+3,myints+6); // 20,25,32 first.swap(second); std::cout << "first contains:"; for (std::set<int>::iterator it=first.begin(); it!=first.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; std::cout << "second contains:"; for (std::set<int>::iterator it=second.begin(); it!=second.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0;}
黑科技之equal_elements
此外,看到一个特别方便的函数叫做equal_elements(),作用是返回一个pair,pair的first指向lower_bound,pair的second指向upper_bound。
// set::equal_elements#include <iostream>#include <set>int main (){ std::set<int> myset; for (int i=1; i<=5; i++) myset.insert(i*10); // myset: 10 20 30 40 50 std::pair<std::set<int>::const_iterator,std::set<int>::const_iterator> ret; ret = myset.equal_range(30); std::cout << "the lower bound points to: " << *ret.first << '\n'; std::cout << "the upper bound points to: " << *ret.second << '\n'; return 0;}是不是特别方便呢?~
存疑
get_allocator() 的用法及意义
// set::get_allocator#include <iostream>#include <set>int main (){ std::set<int> myset; int * p; unsigned int i; // allocate an array of 5 elements using myset's allocator: p=myset.get_allocator().allocate(5); // assign some values to array for (i=0; i<5; i++) p[i]=(i+1)*10; std::cout << "The allocated array contains:"; for (i=0; i<5; i++) std::cout << ' ' << p[i]; std::cout << '\n'; myset.get_allocator().deallocate(p,5); return 0;}
关于集合间逻辑关系操作
四种常用函数标准用法:
#include <algorithm>#include <iostream>#include <set>using namespace std; int main(){ int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; set<int> S( a, a + 9 ); int b[] = { 3, 6, 8, 9 }; set<int> S2( b, b + 4 ); set<int>::iterator site; set<int> Su; set<int> Si; set<int> Sd; set<int> Ssd; //交集 set_intersection( S.begin(), S.end(), S2.begin(), S2.end(), inserter( Si, Si.begin() ) ); //并集 set_union( S.begin(), S.end(), S2.begin(), S2.end(), inserter( Su, Su.begin() ) ); //差集 set_difference( S.begin(), S.end(), S2.begin(), S2.end(), inserter( Sd, Sd.begin() ) ); //对称差集 set_symmetric_difference( S.begin(), S.end(), S2.begin(), S2.end(), inserter( Ssd, Ssd.begin() ) ); site = Si.begin(); cout<<"the intersection of S and S2 is : "; while( site != Si.end() ) { cout<< *site <<" "; ++ site; } cout<<endl; site = Su.begin(); cout<<"the union of S and S2 is : "; while( site != Su.end() ) { cout<< *site <<" "; ++ site; } cout<<endl; site = Sd.begin(); cout<<"the difference of S and S2 is : "; while( site != Sd.end() ) { cout<< *site <<" "; ++ site; } cout<<endl; site = Ssd.begin(); cout<<"the symmetric difference of S and S2 is : "; while( site != Ssd.end() ) { cout<< *site <<" "; ++ site; } cout<<endl; return 0;}
输出:
the intersection of S and S2 is : 3 6 8
the union of S and S2 is : 0 1 2 3 4 5 6 7 8 9
the difference of S and S2 is : 0 1 2 4 5 7
the symmetric difference of S and S2 is : 0 1 2 4 5 7 9
详解用法:
#include<set>#include<iterator>#include<iostream>#include<algorithm>using namespace std;set<int> eg1,eg2;int main(){//插入eg1.insert(1);eg1.insert(100);eg1.insert(5);eg1.insert(1);//元素1因为已经存在所以set中不会再次插入1eg1.insert(10);eg1.insert(9);//遍历set,可以发现元素是有序的set<int>::iterator set_iter=eg1.begin();cout<<"Set named eg1:"<<endl;for(;set_iter!=eg1.end();set_iter++) cout<<*set_iter<<" ";cout<<endl;//使用size()函数可以获得当前元素个数cout<<"Now there are "<<eg1.size()<<" elements in the set eg1"<<endl;if(eg1.find(200)==eg1.end())//find()函数可以查找元素是否存在 cout<<"200 isn't in the set eg1"<<endl;for(int i=6;i<15;i++) eg2.insert(i);cout<<"Set named eg2:"<<endl;for(set_iter=eg2.begin();set_iter!=eg2.end();set_iter++) cout<<*set_iter<<" ";cout<<endl;//获得两个set的并set<int> eg3; cout<<"Union:";set_union(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));//注意第五个参数的形式copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));cout<<endl;//获得两个set的交,注意进行集合操作之前接收结果的set要调用clear()函数清空一下eg3.clear();set_intersection(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));cout<<"Intersection:";copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));cout<<endl;//获得两个set的差eg3.clear();set_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));cout<<"Difference:";copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));cout<<endl;//获得两个set的对称差,也就是假设两个集合分别为A和B那么对称差为AUB-A∩Beg3.clear();set_symmetric_difference(eg1.begin(),eg1.end(),eg2.begin(),eg2.end(),insert_iterator<set<int> >(eg3,eg3.begin()));copy(eg3.begin(),eg3.end(),ostream_iterator<int>(cout," "));cout<<endl;return 0;}输出:
Set named eg1:
1 5 9 10 100
Now there are 5 elements in the set eg1
200 isn't in the set eg1
Set named eg2:
6 7 8 9 10 11 12 13 14
Union:1 5 6 7 8 9 10 11 12 13 14 100
Intersection:9 10
Difference:1 5 100
1 5 6 7 8 11 12 13 14 100
- 【STL-set】set的使用 _STL自学笔记
- stl set的使用
- STL set的使用
- stl中set的使用
- STL中set的使用
- STL容器Set的使用
- 《 set/map 的使用 ----STL》
- L2-005. 集合相似度_STL的 set
- C++ STL Set使用
- STL set简单使用
- c++ STL set 使用
- STL中set使用
- STL------list、set、map的简单使用
- STL set和multiset的使用
- c++ STL set和multiset的使用
- C++ STL set和multiset的使用
- C++ STL set和multiset的使用
- c++ STL set和multiset的使用
- c++编程经验一
- cocos2d-x初探学习笔记(28)--CCTMXTiledMap
- C# 连接 Oracle 的几种方式
- 2014公积金新政策对你买房有什么好处?
- 算法の堆排序
- 【STL-set】set的使用 _STL自学笔记
- cocos2d-x初探学习笔记(29)-cocosBuilder
- MySQL 中文乱码解决
- Java IO
- awk
- 类库调用Response
- 解决vi/vim中粘贴会在行首多很多缩进和空格的问题
- 采用E-C糖葫芦串分析法进行问题分析提高产品质量
- sqlit数据库升级,添加字段