首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

基准模版库学习之关联式容器

2013-03-06 
标准模版库学习之关联式容器setstd::setint isetstd::setint::iterator it iset.insert(4).first(

标准模版库学习之关联式容器

set

std::set<int> iset;
std::set<int>::iterator it = iset.insert(4).first;
(*it)++; // error. 原因:std::set的迭代器不能修改对应的元素.

//语法上不会报错,程序中也可以修改,但会破坏有序性,set可能表现出非预期的行为

这是因为:

std::set的特点是:
1.        对于插入、删除和查找操作,

set保证其时间复杂度都是O(log n);
2.        set是一个有序的、可以前向和后向遍历的容器(双向迭代器);
3.        set是一个元素类型和比较函数可以配置的容器,但是一经配置,就不可更改;
4.        set的元素可以插入、删除,但是不可更改。

set在任何时刻都是一个有序的结构,而一旦破坏这个有序性,set可能表现出非预期的行为。为了保证set的概念完整性,C++STL厉
行规定了3和4两个限制,在绝大部分情况下,这两个限制是合理的。
 但是,当我在set里面存的是shared_ptr元素时, 根本无所谓有没有序. 我就是要通过迭代器获取元素的非const引用. 解决如下:
#include <iostream>
#include <set>

template<class T>
inline T & GetStdSetElement(std::_Rb_tree_const_iterator<T>  std_set_iterator)
{
    return *(T *)&(*std_set_iterator);
}


int main()
{    
    using namespace std;

    set<int> iset;
    pair< set<int>::iterator, bool> res = iset.insert(4);
    
    int & i = GetStdSetElement(res.first);
    i++;
    
    cout << *( iset.begin() ) << endl;
    
    return 0;
}

 

/*目的:学习set容器的使用*程序输出:6 5 4 3 2 14 already exists1 2 3 4 5 61 element(s) removed3 4 6*coll2.erase(coll2.begin(), coll2.find(val));*当coll2中不存在值等于val的元素时,会返回一个指向结尾的迭代器。*此时,coll2.erase(coll2.begin(), coll2.find(val));会删除coll2中所有元素。*/#include <iostream>#include <set>using namespace std;int main(){typedef set<int, greater<int> > IntSet;  //只是构造时,创建了一个从大到小排列的容器,默认为从小到大。// TEMPLATE CLASS set/*template<class _Kty,class _Pr = less<_Kty>,class _Alloc = allocator<_Kty> >class set: public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false> >:*/IntSet IntSetcoll;IntSetcoll.insert(4);IntSetcoll.insert(3);IntSetcoll.insert(5);IntSetcoll.insert(1);IntSetcoll.insert(6);IntSetcoll.insert(2);IntSetcoll.insert(5);set<int> setcoll;//默认为从小到大。setcoll.insert(4);setcoll.insert(3);setcoll.insert(5);setcoll.insert(1);setcoll.insert(6);setcoll.insert(2);setcoll.insert(5);IntSet::iterator pos;for (pos = IntSetcoll.begin(); pos != IntSetcoll.end(); ++pos){cout << *pos << ' ';}cout << endl;pair<IntSet::iterator, bool> status = IntSetcoll.insert(4);if (status.second){cout << "4 inserted as element "<< distance(IntSetcoll.begin(), status.first) + 1 << endl;}else{cout << "4 already exists" << endl;}set<int> coll2(IntSetcoll.begin(), IntSetcoll.end());copy(coll2.begin(), coll2.end(), ostream_iterator<int>(cout, " "));cout << endl;coll2.erase(coll2.begin(), coll2.find(3));int num;num = coll2.erase(5);cout << num << " element(s) removed" << endl;copy(coll2.begin(), coll2.end(), ostream_iterator<int>(cout, " "));cout << endl;getchar();}


 

/*目的:学习set容器的使用(二)*程序输出:coll1: 1 2 4 5 6 7coll2: 7 6 5 4 2 1coll1: 7 6 5 4 3 2 1coll1 and coll2 have same sorting criterion*RuntimeCmp(cmp_mode m = normal) : mode(m)*不能改为RuntimeCmp() : mode(normal)*带参数的构造函数,用来在程序运行中构造对象时传递参数*///print.hpp头文件#include <iostream>/* PRINT_ELEMENTS()*- print optional C-string optcstr followed by*- all elements of the collection coll*- separated by spaces*/template <class T>inline void PRINT_ELEMENTS (const T& coll, const char* optcstr = ""){typename T::const_iterator pos;std::cout << optcstr;for (pos = coll.begin(); pos != coll.end(); ++pos){std::cout << *pos << ' ';}std::cout << std::endl;}#include <iostream>#include <set>//#include "print.hpp"using namespace std;template <class 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) const{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 &set);                                                       //stl的函数声明方式int main(){IntSet coll1;fill(coll1);PRINT_ELEMENTS(coll1, "coll1: ");RuntimeCmp<int> reverse_order(RuntimeCmp<int>::reverse);IntSet coll2(reverse_order);fill(coll2);PRINT_ELEMENTS(coll2, "coll2: ");coll1 = coll2;coll1.insert(3);PRINT_ELEMENTS(coll1, "coll1: ");if (coll1.value_comp() == coll2.value_comp()){cout << "coll1 and coll2 have same sorting criterion" << endl;}else{cout << "coll1 and coll2 have different sorting criterion" << endl;}getchar();}void fill(IntSet &set){set.insert(4);set.insert(7);set.insert(5);set.insert(1);set.insert(6);set.insert(2);set.insert(5);}


map

/*目的:学习map容器的使用。本事例运用Maps、Strings并于执行期指定排序准则事例程序*程序输出:Bestatter       undertakerDeutschland     GermanyHaken           snagHund            dogUnternehmen     enterprisearbeiten        workdeutsch         Germangehen           walkunternehmen     undertakearbeiten        workBestatter       undertakerdeutsch         GermanDeutschland     Germanygehen           walkHaken           snagHund            dogUnternehmen     undertake*/#include <iostream>#include <iomanip>#include <map>#include <string>#include <algorithm>using namespace std;/* function object to compare strings* - allows you to set the comparison criterion at runtime* - allows you to compare case insensitive*/class RuntimeStringCmp{public:enum cmp_mode {normal, nocase};private:const cmp_mode mode;static bool nocase_compare(char c1, char c2){return toupper(c1) < toupper(c2);}public:RuntimeStringCmp(cmp_mode m = normal) : mode(m){}bool operator() (const string &s1, const string &s2) const{if (mode == normal){return s1 < s2;} else{return lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), nocase_compare);}}};/*  container type* - map with* - string keys* - string values* - the special comparison object type*/typedef map<string, string, RuntimeStringCmp> StringStringMap;      //function that fills and prints such containersvoid fillAndPrint(StringStringMap &coll);                                                       //stl的函数声明方式int main(){//create a container with the default comparison criterionStringStringMap coll1;fillAndPrint(coll1);//create an objectRuntimeStringCmp ignorecase(RuntimeStringCmp::nocase);//create a containerStringStringMap coll2(ignorecase);fillAndPrint(coll2);getchar();}void fillAndPrint(StringStringMap &coll){coll["Deutschland"] = "Germany";coll["deutsch"] = "German";coll["Haken"] = "snag";coll["arbeiten"] = "work";coll["Hund"] = "dog";coll["gehen"] = "go";coll["Unternehmen"] = "enterprise";coll["unternehmen"] = "undertake";coll["gehen"] = "walk";coll["Bestatter"] = "undertaker";//printStringStringMap::iterator pos;cout.setf(ios::left, ios::adjustfield);for (pos = coll.begin(); pos != coll.end(); ++pos){cout <<setw(15) << pos->first.c_str() << " " <<pos->second << endl;}cout << endl;}

热点排行