STL与泛型编程<五>:Sets和Multisets
来源:互联网 发布:mac用什么绘画软件 编辑:程序博客网 时间:2024/06/07 09:40
set和multiset会根据特定的排序准则排序,自动将元素进行排序,不同之处在于multiset允许元素重复而set不允许。
其声明如下
namespace std{ template<class T, class Compare = less<T>, class Allocator = allocator<T> > class set; template<class T, class Compare = less<T>, class Allocator = allocator<T> > class multiset;}/*这里的T就是set::key_type/value_type;这里的 Compare就是set::key_cmpare/value_cmpare;对于set,key就是value,value就是key*/
如果没有传入特别的排序准则,就采用缺省的准则less-这是一个仿函数,以operator < 对元素进行比较。
sets和multisets的能力
sets和multisets通常以平衡二叉树(红黑树)完成(见下图),自动排序的主要优点在于其搜寻算法具有对数复杂度。但是也造成个限制你不能直接改变元素值,因为这会打乱原本正确的顺序。因此要改变元素值,必须先删除就元素,再插入新元素
sets和multisets的操作函数
- 生成 复制 销毁
非变动性操作
元素的比较动作只能比较型别相同(元素和排序准则都必须相同)的元素
特殊的搜寻函数
equal_range则是将lower_bound()和upper_bound()的返回值做成一个pair返回,所以它返回的是“与参数值相等”的元素所形成的区间,如果lower_bound()或“equal_range()的第一值”等于“equal_range()的第二值”或upper_bound(),则此set或multiset内部存在相同的数值。见下面例子
#include <set>#include <algorithm>#include <iostream>using namespace std;int main(void){ set<int> col; col.insert(1); col.insert(2); col.insert(4); col.insert(5); col.insert(6); cout << "lower_bound(3): " << *col.lower_bound(3) << endl; // 4 cout << "upper_bound(3): " << *col.upper_bound(3) << endl; // 4 cout << "equal_range(3): " << *col.equal_range(3).first << " "<< *col.equal_range(3).second << endl;// 4 4 cout << endl; cout << "lower_bound(5): " << *col.lower_bound(5) << endl;//5 cout << "upper_bound(5): " << *col.upper_bound(5) << endl;//6 cout << "equal_range(5): " << *col.equal_range(5).first << " " << *col.equal_range(5).second << endl;//5 6 return 0; }
赋值
这些操作函数,赋值操作的两端容器必须具有同的型别
迭代器相关函数
注意这里的迭代器是双向迭代器,对于只能用于随机迭代器的STL算法来说,就不能使用了,也不能对其调用任何变动性算法,如remove。
元素的安插和移除
sets提供以下接口:
/*pair结构中的second表示安插是否成功,first成员返回新元素的位置,或返回现存的同值元素的位置。*/pair<iterator,bool> insert(const value_type& elem);iterator insert(iterator pos_hint,const value_type& elem);
因此可以如下使用
set<double> c;if (c.insert(3.3).second){ cout << "3.3 inserted " << endl;}else{ cout << "3.3 already exits " << endl;}
multisets提供以下接口
iterator insert(const value_type& elem);iterator insert(iterator pos_hint,const value_type& elem);
返回值型别的不同是因为set不允许重复,而multisets允许重复,因此如果将某元素安插至一个set内,而该set已经内含同值元素,则安插失败。
一个示例
#include <set>#include <algorithm>#include <iostream>#include <iterator>using namespace std;int main(void){ typedef set<int,greater<int> > IntSet; IntSet col1; col1.insert(4); col1.insert(3); col1.insert(5); col1.insert(1); col1.insert(6); col1.insert(2); col1.insert(5); IntSet::iterator pos; for (pos=col1.begin(); pos!=col1.end(); ++pos) { cout << *pos << endl; //6 5 4 3 2 1 } cout << endl; //插入4 pair<IntSet::iterator,bool> status = col1.insert(4); if (status.second) { cout << "4 inserted as element" << distance(col1.begin(),status.first) + 1 << endl; } else { cout << "4 already exits" << endl; //打印 } set<int> col2(col1.begin(),col1.end()); copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); // 1 2 3 4 5 6 cout << endl; //移除3 col2.erase(col2.begin(),col2.find(3)); // 3 4 5 6注意3没被移除,一般区间处理都是左闭右开 int num; num = col2.erase(5); cout << num << " element(s) removed" << endl; //3 4 6 copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //3 4 6 cout << endl; return 0;}
对于multisets,上诉程序如下
#include <set>#include <algorithm>#include <iostream>#include <iterator>using namespace std;int main(void){ typedef multiset<int,greater<int> > IntSet; IntSet col1; col1.insert(4); col1.insert(3); col1.insert(5); col1.insert(1); col1.insert(6); col1.insert(2); col1.insert(5); IntSet::iterator pos; for (pos=col1.begin(); pos!=col1.end(); ++pos) { cout << *pos << endl; //6 5 5 4 3 2 1 } cout << endl; //插入4 IntSet::iterator ipos = col1.insert(4); //insert返回新元素的位置 cout << "4 inserted as element" << distance(col1.begin(),ipos) + 1 << endl; //5 multiset<int> col2(col1.begin(),col1.end()); copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); // 1 2 3 4 4 5 5 6 cout << endl; //移除3 col2.erase(col2.begin(),col2.find(3)); // 3 4 4 5 5 6 int num; num = col2.erase(5); cout << num << " element(s) removed" << endl; //2 copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); //3 4 4 6 cout << endl; return 0;}
在此处输入标题
补充
有两种方式定义排序准则
1. 以template参数定义之(就是将排序准则当作是容器的类型,当然更推荐这种)
2. 以构造函数参数定义
至于2见以下程序
#include <iostream>#include <set>#include <algorithm>#include <iterator> using namespace std;template<typename T>class RuntimeCmp{ public: enum cmp_mode {normal, reverse}; private: cmp_mode mode; public: RuntimeCmp(cmp_mode m=normal) : mode(m) {} bool operator() (const T& t1, const T& t2)//必须得提供此函数 { return mode == normal ? t1 < t2 : t2 < t1; } bool operator == (const RuntimeCmp& rc) { return mode == rc.mode; }};typedef set<int, RuntimeCmp<int> > IntSet;void fill(IntSet& col);int main(void){ IntSet col; fill(col); copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); cout << endl; RuntimeCmp<int> reverse_order(RuntimeCmp<int>::reverse); IntSet col2(reverse_order); fill(col2); copy(col2.begin(),col2.end(),ostream_iterator<int>(cout," ")); cout << endl; col = col2; //排序准则也赋值了 col.insert(3); copy(col.begin(),col.end(),ostream_iterator<int>(cout," ")); cout << endl; if (col.value_comp() == col2.value_comp()) cout << "col and col2 have the same sort" << endl; return 0;}void fill(IntSet& col){ col.insert(4); col.insert(7); col.insert(5); col.insert(1); col.insert(6); col.insert(2); col.insert(5);}/*算是自定义排序准则,一定得在自定义型别中重载operator()操作符,且在词函数中定义排序准则。*/
此外set容器还提供了两个函数
key_compare key_comp() const;value_compare value_comp() const;
下面见一个例子
#include <iostream>#include <set>int main (void){ std::set<int> myset; int highest; std::set<int>::key_compare mycomp = myset.key_comp(); //默认为less仿函数 for (int i=0; i<=5; i++) myset.insert(i); std::cout << "myset contains:"; highest=*myset.rbegin(); //最后一个元素,按照less的排序准则,应该是最大的 std::cout << highest << std::endl; //果然是5 std::set<int>::iterator it=myset.begin(); do { std::cout << ' ' << *it; } while ( mycomp(*(++it),highest) ); std::cout << '\n'; return 0;}/*less原型: template <class T> struct less : binary_function <T,T,bool> { bool operator() (const T& x, const T& y) const {return x<y;}};*/
- STL与泛型编程<五>:Sets和Multisets
- STL系列(8): Sets & MultiSets
- STL学习记录(八)Sets、Multisets
- C++ Sets & MultiSets
- C++ Sets & MultiSets
- STL容器Set和Multisets使用
- 关联式容器:Sets、Multisets、Maps、Multimaps
- STL与泛型编程<四>:List
- 泛型编程与STL
- 泛型编程与STL
- STL与泛型编程
- STL与泛型编程
- 泛型编程与STL
- 《泛型编程与stl》
- 泛型编程与STL
- STL与泛型编程<六>:map和multimap
- Sets-STL
- Codeforce GCD Table STL中的multisets
- Pro Git 中文版——Git 分支
- 634A.Island Puzzle
- Android中关于SimpleAdapter的简单理解
- YTU 1055: 输入字符串以及输出
- Pro Git中文版——服务器上的 Git
- STL与泛型编程<五>:Sets和Multisets
- 关于svn无法连接的问题
- 资产组合优化原理与实例 Portfolio Optimization
- Pro Git中文版——分布式 Git
- 633A.Ebony and Ivory
- sbt 安装以及编译spark程序
- Vulkan资料搜集--链接,更新
- eclipse导入项目不显示svn信息
- IOS 成员变量,全局变量,局部变量定义,static与extern的区别