[置顶] STL——set && map的使用
2018-04-04 19:56
393 查看
set set实现了红黑树(RBTree)平衡二叉搜索树的数据结构,模板参数为key,相当于是K模型的集合。 在插入元素时会自动调整二叉树,使其尽量保持平衡,以至于在树中进行搜索时,能够达到logn的搜索效率,对于重复插入的值,会插入失败。
使用时,记得加上头文件哦!
由于set底层为RBTree,所以不能有重复值的元素,在上面的代码中,尽管插入了两次15,但输出结果中只有一个,那是因为只有第一次插入成功,第二次则插入失败。
2 元素的删除 set.erase()
3 元素的查找 set.find()
4 使用rbegin和rend进行反向遍历
由输出结果可看出,反向遍历时定义的反向迭代器,相当于在建RBTree时,让较大的为左孩子,较小的为右孩子。
5 一个例题,熟悉set的其他接口找出两组字符串的相同和不同的
map
map和set原理相同,只不过map的模板参数有两个,分别为key和value,是KV模型的映射集合。 在STL库中,将这两个参数放到了一个名为pair的结构体中,key和value分别对应的是pair结构体中的first和second。
使用map前也要记得加上它的头文件呦!
map底层是RETree,在排序时是依据key进行的。
2 元素的删除 map.erase()
3 元素的查找 map.find()
4 元素的修改 借助find进行
5 使用map统计单词出现的次数(1)统计单词出现的次数,map的两个参数类型应该为map<string,size_t>;(2)insert的返回值是pair<iterator,bool>,其中bool表示是否插入成功;
6 解析operator[] 首先我们观察一下insert的返回值:
吼吼!这样就明白为什么可以 CountMap[str[i]]++来统计次数啦!其实,operator[]的使用非常广泛,可以进行创建和修改,来看一下:
multiset && multimap1 multiset和set类似,没有单独需要包的头文件,实现的是可重复的set;2 multimap和map类似,也没有单独需要包的头文件,仍为:#include <map>,实现的是可重复的map。验证一下他们的使用:
使用时,记得加上头文件哦!
#include <set>1 元素的插入 set.insert()
void test_set() { set<int> s1; s1.insert(10); s1.insert(15); s1.insert(13); s1.insert(19); s1.insert(16); s1.insert(15); set<int>::iteratorit1; //定义迭代器,方便访问数据 it1 = s1.begin(); //s1.begin返回第一个元素的迭代器(即树中最左端元素) while(it1 != s1.end()) //s1.end返回最后一个元素的下一个迭代器 { cout << *it1 <<" "; it1++; } cout << endl; }输出结果为:
由于set底层为RBTree,所以不能有重复值的元素,在上面的代码中,尽管插入了两次15,但输出结果中只有一个,那是因为只有第一次插入成功,第二次则插入失败。
2 元素的删除 set.erase()
//erase 需要借助find()找到需要删除的数据的迭代器 it1 = s1.find(15); s1.erase(it1); for(it1 = s1.begin(); it1 != s1.end(); ++it1) { cout << *it1 <<" "; } cout << endl;输出结果为:
3 元素的查找 set.find()
//find 返回的是元素的迭代器 it1 = s1.find(15); if(it1 != s1.end()) cout << *it1 << endl; else cout <<"no find!" << endl; it1 = s1.find(15); s1.erase(it1); it1 = s1.find(30); if(it1 != s1.end()) cout << *it1 << endl; else cout <<"no find!" << endl;输出结果为:
4 使用rbegin和rend进行反向遍历
//使用rbegin和rend进行反向遍历 set<int>::reverse_iteratorit2;//定义反向迭代器 it2 = s1.rbegin(); while(it2 != s1.rend()) { cout << *it2 <<" "; it2++; } cout << endl;输出结果为:
由输出结果可看出,反向遍历时定义的反向迭代器,相当于在建RBTree时,让较大的为左孩子,较小的为右孩子。
5 一个例题,熟悉set的其他接口找出两组字符串的相同和不同的
void test_set1() { set<string> s1; set<string> s2; s1.insert("set"); s1.insert("sort"); s1.insert("string"); s2.insert("set"); s2.insert("sort"); s2.insert("string"); s2.insert("map"); s2.insert("test"); set<string> diffs;//不同 set<string> sames;//相同 set<string>::iteratorit1 = s1.begin(); set<string>::iteratorit2 = s2.begin(); while(it1 != s1.end() && it2 != s2.end()) { if(*it1 < *it2) { diffs.insert(*it1); it1++; } elseif(*it1 > *it2) { diffs.insert(*it2); it2++; } else { sames.insert(*it1); it1++; it2++; } } if(it1 != s1.end()) { while(it1 != s1.end()) { diffs.insert(*it1); it1++; } } else { while(it2 != s2.end()) { diffs.insert(*it2); it2++; } } cout <<"different:"; for(it1 = diffs.begin(); it1 != diffs.end(); ++it1) { cout << *it1 <<" "; } cout << endl <<"same:"; for(it2 = sames.begin(); it2 != sames.end(); ++it2) { cout << *it2 <<" "; } cout << endl; }输出结果:
map
map和set原理相同,只不过map的模板参数有两个,分别为key和value,是KV模型的映射集合。 在STL库中,将这两个参数放到了一个名为pair的结构体中,key和value分别对应的是pair结构体中的first和second。
使用map前也要记得加上它的头文件呦!
#include<map>1 元素的插入 map.insert()
//insert map<string,string> m1; m1.insert(pair<string,string>("insert","插入")); m1.insert(pair<string,string>("sort","排序")); m1.insert(pair<string,string>("return","返回")); m1.insert(pair<string,string>("erase","删除")); map<string,string>::iteratorit1; for(it1 = m1.begin(); it1 != m1.end(); ++it1) { cout << it1->first <<":" << it1->second << endl; }输出结果为:
map底层是RETree,在排序时是依据key进行的。
2 元素的删除 map.erase()
//erase it1 = m1.find("erase"); m1.erase(it1); for(it1 = m1.begin(); it1 != m1.end(); ++it1) { cout << it1->first <<":" << it1->second << endl; }输出结果为:
3 元素的查找 map.find()
//find 在使用find时可以看到,参数只有一个key value //因为map中每一个节点的内容是一个pair的结构体,只根据一个参数便可以找到这个节点 it1 = m1.find("erase"); cout << it1->second << endl;输出结果为:
4 元素的修改 借助find进行
//借助find对元素的修改 //修改时应注意,只能对第二个参数mapped value进行修改,否则会破坏RBTree it1 = m1.find("erase"); it1->second ="erase"; for(it1 = m1.begin(); it1 != m1.end(); ++it1) { cout << it1->first <<":" << it1->second << endl; }输出结果为:
5 使用map统计单词出现的次数(1)统计单词出现的次数,map的两个参数类型应该为map<string,size_t>;(2)insert的返回值是pair<iterator,bool>,其中bool表示是否插入成功;
void test_mapcount() { map<string,size_t> CountMap; stringstr[] = { "insert","sort","return" ,"insert"}; pair<map<string,size_t>::iterator,bool> ret; for(size_ti = 0; i < sizeof(str) /sizeof(str[0]); ++i) { ret = CountMap.insert(make_pair(str[i], 1)); if(ret.second == false) { //ret.first->second++; CountMap[str[i]]++; } } map<string,size_t>::iteratorit; for(it = CountMap.begin(); it != CountMap.end(); ++it) { cout << it->first <<":" << it->second << endl; } }输出结果为:
6 解析operator[] 首先我们观察一下insert的返回值:
pair<iterator,bool> insert (const value_type& val);可以看到,insert的返回值是pair<iterator,bool>,所以它返回的是插入的这一点的迭代器,和是否插入成功的bool。 在了解了insert的返回值后,步入正题,开始探究operator[]的实现:
mapped_type&operator[] (constkey_type& k) { return(*((this->insert(make_pair(k, mapped_type()))).first)).second; }一步步分析:
吼吼!这样就明白为什么可以 CountMap[str[i]]++来统计次数啦!其实,operator[]的使用非常广泛,可以进行创建和修改,来看一下:
void test() { map<string,string> m; map<string,string>::iteratorit; m["string"]; m["string"] = "字符串"; m["return"] = "返回"; }调试过程中m为:
multiset && multimap1 multiset和set类似,没有单独需要包的头文件,实现的是可重复的set;2 multimap和map类似,也没有单独需要包的头文件,仍为:#include <map>,实现的是可重复的map。验证一下他们的使用:
void test_multiset() { multiset<int> ms; ms.insert(5); ms.insert(7); ms.insert(6); ms.insert(5); multiset<int>::iteratorit; for(it = ms.begin(); it != ms.end(); ++it) { cout << *it <<" "; } cout << endl; } void test_multimap() { multimap<string,string> mm; mm.insert(make_pair("string","字符串")); mm.insert(make_pair("left","左边")); mm.insert(make_pair("left","剩余")); mm.insert(make_pair("test","测试")); multimap<string,string>::iteratorit; for(it = mm.begin(); it != mm.end(); ++it) { cout << it->first <<":"<<it->second<<endl; } }输出结果为:
相关文章推荐
- STL中list,vector,deque,map,set区别、联系和使用场景
- 高效的使用stl::map和std::set
- STL之std::set、std::map的lower_bound和upper_bound函数使用说明
- 【STL学习】map&set
- ZOJ Problem Set - 3860Find the Spy (STL-> map 建立简单查询表 )
- STL中list,vector,deque,map,set区别、联系和使用场景原理
- STL中list,vector,deque,map,set区别、联系和使用场景
- STL中的容器使用比较(string vector list deque set map)
- 使用linux的GDB打印STL(vector,map,set..................)
- C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用
- STL浅析set&map
- STL------list、set、map的简单使用
- stl容器区别(内存布局和使用场合): vector list deque set map
- poj 3320 Jessica's Reading Problem 【尺取法+STLmap set】
- C/C++--STL中list,vector,deque,map,set区别、联系和使用场景
- STL之关联容器(pair、map、set的使用)
- C++中防止STL中迭代器失效__map/set等关联容器vector/list/deque等序列容器_如何防止迭代器失效_即erase()的使用
- C++ STL容器的学习使用(vector、queue、list、set、map)
- STL中list,vector,deque,map,set区别、联系和使用场景
- c++ stl 使用汇总(string,vector,map,set)