STL--set注意事项
2015-11-24 20:09
483 查看
混杂着记录的,可能会比较乱,但是都是一些有用的点
1.insert
单参数的insert: The first version return a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element that already had its same value in the set. The pair::second element in the pair is set to true if a
new element was inserted or false if an element with the same value existed.
双参数的insert: The second version returns an iterator pointing to either the newly inserted element or to the element that already had its same value in the set.
双参数insert允许对x将要插入的位置的线索说明。如果线索给的精确,那么插入会很快。如果不精确的话就需要用常规的插入算法来完成,此时与单参数的insert相同。
单参数的耗时1856毫秒,双参数的耗时920毫秒,正确使用insert可以减少插入的时间。
2.set的第二个模板参数
默认情况下,排序操作使用less<Object>函数对象实现,而该函数对象是通过对Object调用operator<来实现的
比如判断相等:!(isLessThan(lhs, rhs) || isLessThan(rhs, lhs))
例如可以生成一个存储string对象的set,通过使用CaseInsensitiveCompare函数对象来忽略字符的大小写
⑴以template参数定义之
例如 std::set<int, std::greater<int> > coll;
这种情况下排序准则就是型别的一部分,因此型别系统确保“只有排序准则相同的容器才能被合并”。实际的排序准则是容器所产生的函数对象(functor,仿函数)。
在coll的构造函数内会自动生成class PersonSortCriterion的一个实体,所有的元素都将以此为排序准则进行排序。
你无法将这个set拿来和“拥有不同排序准则”的其他set合并或互相赋值。
⑵以构造函数参数定义之。
这种情况下,同一个型别可以运用不同的排序准则,而排序准则的初始值或状态也可以不同。
如果执行期才获得排序准则,而且需要用到不同的排序准则(但数据型别必须相同),这个方法可以派上用场。
4.迭代器性质
和其他所有关联式容器类似,这里的迭代器是双向迭代器(bidirectional iterator)。
所以对于只能用于随机存取迭代器(random access iterator)的STL算法(例如排序或随机乱序random_shuffling),set和multiset就用不了了。
更重要的是,对迭代器操作而言,所有元素都被视为常数。set<int> iter = iSet.begin(); *iter = 1; // Error:不可修改的左值
这可以确保你不会人为改变元素值,从而打乱既定顺序。然而也使得你无法对sets或multisets元素调用任何变动性算法(modifying algorithms)
例如你不能对它调用remove(),因为remove()算法实际上是一个参数值覆盖被移除的元素,如果要移除set和multisets的元素,你只能使用它们所提供的成员函数。
c
co
Com
Comp
Compa
Compar
compari
comparis
comparis
compariso
comparison
1.insert
pair<iterator, bool> insert(const value_type& x); iterator insert(iterator position, const value_type& x);
单参数的insert: The first version return a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element that already had its same value in the set. The pair::second element in the pair is set to true if a
new element was inserted or false if an element with the same value existed.
双参数的insert: The second version returns an iterator pointing to either the newly inserted element or to the element that already had its same value in the set.
双参数insert允许对x将要插入的位置的线索说明。如果线索给的精确,那么插入会很快。如果不精确的话就需要用常规的插入算法来完成,此时与单参数的insert相同。
set<int> iSet1, iSet2; for (int i = 0; i < 100000; ++i) iSet1.insert(i); for (int i = 0; i < 100000; ++i) iSet2.insert(iSet2.end(), i);
单参数的耗时1856毫秒,双参数的耗时920毫秒,正确使用insert可以减少插入的时间。
2.set的第二个模板参数
默认情况下,排序操作使用less<Object>函数对象实现,而该函数对象是通过对Object调用operator<来实现的
比如判断相等:!(isLessThan(lhs, rhs) || isLessThan(rhs, lhs))
例如可以生成一个存储string对象的set,通过使用CaseInsensitiveCompare函数对象来忽略字符的大小写
class CaseInsensitiveCompare { public: bool operator()(const string& lhs, const string& rhs) { return stricmp(lhs.c_str(), rhs.c_str()) < 0; } }; int main() { set<string, CaseInsensitiveCompare> s; s.insert("hello"); s.insert("HellO"); cout << s.size(); // 1 return 0; }3.排序准则
⑴以template参数定义之
例如 std::set<int, std::greater<int> > coll;
这种情况下排序准则就是型别的一部分,因此型别系统确保“只有排序准则相同的容器才能被合并”。实际的排序准则是容器所产生的函数对象(functor,仿函数)。
class Person { public: string firstname()const; string lastname()const; }; class PersonSortCriterion { public: bool operator()(const Person& p1, const Person& p2)const { /** * p1的姓小于p2的姓 * 当姓相等时候p1的名字小于p2的名字 */ return p1.lastname() < p2.lastname() || ((!(p2.lastname() < p1.lastname())) && p1.firstname() < p2.firstname()); } }; int main() { typedef set<Person, PersonSortCriterion> PersonSet; PersonSet coll; PersonSet::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { // ... } return 0; }这个就是仿函数,用类的operator()取代一般函数,一般函数无法做到成为一个类别。所以可以用仿函数来当set的template参数。
在coll的构造函数内会自动生成class PersonSortCriterion的一个实体,所有的元素都将以此为排序准则进行排序。
你无法将这个set拿来和“拥有不同排序准则”的其他set合并或互相赋值。
⑵以构造函数参数定义之。
这种情况下,同一个型别可以运用不同的排序准则,而排序准则的初始值或状态也可以不同。
如果执行期才获得排序准则,而且需要用到不同的排序准则(但数据型别必须相同),这个方法可以派上用场。
// type for sorting criterion template <class T> class RuntimeCmp { public: enum cmp_mode{ normal, reverse }; private: cmp_mode mode; public: // constructor for sorting criterion // - default criterion uses value normal RuntimeCmp(cmp_mode m = normal) :mode(m) {} // comparison of elements bool operator()(const T& t1, const T& t2)const { return mode == normal ? t1 < t2 : t2 < t1; } // comparison of sorting criteria bool operator==(const RuntimeCmp& rc) { return mode == rc.mode; } }; typedef set<int, RuntimeCmp<int> > IntSet; void fill(IntSet& set); int main() { // create, fill, and print set with normal element order // - uses default sorting criterion IntSet coll1; fill(coll1); PRINT_ELEMENT(coll1, "coll1: "); // 1 2 4 5 6 7 // create sorting criterion with reverse element order RuntimeCmp<int> reverse_order(RuntimeCmp<int>::reverse); // create, fill, and print set with reverse element order IntSet coll2(reverse_order); fill(coll2); PRINT_ELEMENT(coll2, "coll2: "); // 7 6 5 4 2 1 // assign elements AND sorting criterion coll1 = coll2; PRINT_ELEMENT(coll1, "coll1: "); // 7 6 5 4 2 1 coll1.insert(3); PRINT_ELEMENT(coll1, "coll1: "); // 7 6 5 4 3 2 1 // just to make sure... if (coll1.value_comp() == coll2.value_comp()) { // true cout << "coll1 and coll2 have same sorting criterion" << endl; } else { cout << "coll1 and coll2 have different sorting criterion" << endl; } return 0; } void fill(IntSet& set) { // fill insert elements in random order set.insert(4); set.insert(7); set.insert(5); set.insert(1); set.insert(6); set.insert(2); set.insert(5); }这个例子说明了如果准则不同,准则本身也会被赋值(assigned)或交换(swapped)。
4.迭代器性质
和其他所有关联式容器类似,这里的迭代器是双向迭代器(bidirectional iterator)。
所以对于只能用于随机存取迭代器(random access iterator)的STL算法(例如排序或随机乱序random_shuffling),set和multiset就用不了了。
更重要的是,对迭代器操作而言,所有元素都被视为常数。set<int> iter = iSet.begin(); *iter = 1; // Error:不可修改的左值
这可以确保你不会人为改变元素值,从而打乱既定顺序。然而也使得你无法对sets或multisets元素调用任何变动性算法(modifying algorithms)
例如你不能对它调用remove(),因为remove()算法实际上是一个参数值覆盖被移除的元素,如果要移除set和multisets的元素,你只能使用它们所提供的成员函数。
c
co
Com
Comp
Compa
Compar
compari
comparis
comparis
compariso
comparison
相关文章推荐
- 多维数组的表示
- ERROR 2006 (HY000): MySQL server has gone away
- HDOJ 2063 过山车 (二分图匹配)
- 《C++ primer》英文第五版阅读笔记(十七)——自增和自减运算符
- 明确工作职责的重要性
- tomcat线程池调优
- 怎样阅读论文(台湾彭明辉)
- 公司岗位层级与职责
- 组建团队
- An error has occurred. See error log for more details.关于这个问题的小谈
- 二分图匹配模板
- Gulp插件less的使用
- 巧用枚举类型,实现项目的多语言切换
- iOS UIWebView和网页的交互(OC中调执行JS)
- 二叉树的简单操作
- 黑马程序员——C语言——函数
- 1【学校教学系统】App总论
- 基于QT5的opencv学习之《学习opencv课后练习3-7》
- c++ new
- ios jsbrige