STL : setmap

tech2022-09-14  104

文章目录

set / multiset构造 和 赋值set大小和交换set插入和删除set查好和统计set 和 multiset 的区别pair对组的创建set容器排序内置数据类型自定义数据类型 map / multimap map容器的构造和赋值map的大小和交换map插入和删除查找和统计map排序内置数据类型自定义数据类型 STL案例--员工分组

set / multiset

所有元素在插入式就会自动排好序set 和 multiset都是关联式容器, 底层是二叉树实现set 和 multiset的区别 set 中不允许有重复元素 (插入重复数据也不会报错, 只是不在里面)multiset 可以有重复元素

构造 和 赋值

void printSet(const set<int>& s) { for(auto it = s.begin(); it != s.end(); it++) { cout<<(*it)<<endl; } } void test01() { set<int> s1; s1.insert(10); s1.insert(30); s1.insert(40); s1.insert(10); s1.insert(20); printSet(s1); cout<<endl; set<int> s2(s1); printSet(s2); cout<<endl; set<int> s3; s3 = s1; printSet(s3); } int main() { test01(); return 0; }

set大小和交换

swap(s1, s2), s1.swap(s2) 均可不可以指定大小, 因为默认填充的话就有重复0了

set插入和删除

set查好和统计

count()函数, 对于set而言只有0或1, multiset才有多种可能用count更好判断某个元素在不在set中 auto it = s1.find(40); if (it == s1.end()) cout<<"wei zhao dao"<<endl; else cout<<(*it)<<endl;

set 和 multiset 的区别

. 运算符的优先级 和 括号是同一级的 set<int> s1; pair<set<int>::iterator, bool> p1 = s1.insert(10); cout<<(*(p1.first))<<" "<<p1.second<<endl; pair<set<int>::iterator, bool> p2 = s1.insert(10); cout<<(*(p2.first))<<" "<<p2.second<<endl; cout<<endl; multiset<int> s2; auto it1 = s2.insert(10); cout<<(*it1)<<endl; auto it2 = s2.insert(10); cout<<(*it2)<<endl;

pair对组的创建

成对出现的数据, 利用对组可以一次性返回两个数据

// 不需要包含头文件 pair<string, int> p1 = make_pair("yyy", 20); pair<string, int> p2("yw", 40); cout<<p1.first<<" "<<p1.second<<endl; cout<<p2.first<<" "<<p2.second<<endl;

set容器排序

set容器默认排序从小到大, 如何变成从大到小?利用仿函数, 改变排序规则, 必须在插入之前就改变排序规则仿函数实际上是一种数据类型, 重载()运算符. 最后需要加上const, 表明不能在函数内部修改变量

内置数据类型

class MyCmp { public: bool operator() (int n, int m) const{ return n > m; } }; void test03() { set<int, MyCmp> s; s.insert(10); s.insert(20); s.insert(30); s.insert(40); for(auto it = s.begin(); it != s.end(); it++) { cout<<*it<<endl; } }

自定义数据类型

class Person { public: string name; int age; Person(string name, int age) : name(name), age(age) {} }; class MyComp { public: bool operator() (const Person& p1, const Person& p2) const{ return p1.age > p2.age; } }; void test04() { set<Person, MyComp> s; s.insert(Person("y", 21)); s.insert(Person("yy", 22)); s.insert(Person("yyy", 23)); s.insert(Person("yyyyy", 24)); for (auto it = s.begin(); it != s.end(); it++) { cout<<"name : "<<it->name<<"\tage : "<<it->age<<endl; } }

map / multimap

map中所有元素都是pair

pair中第一个元素为key(键), 第二个元素为value(实值)

所有元素都会根据元素的键值自动排序

map/multimap 属于关联式容器, 底层结构也是用二叉树实现

优点 (高效): 可以根据key值快速找到value值

map 和 multimap的区别

map不允许容器中有重复key值元素(但是value值可以重复)multimap中允许容器中有重复key值元素

map容器的构造和赋值

#include <iostream> #include <map> using namespace std; void printMap(const map<int, int>& m) { for(map<int, int>::const_iterator it = m.begin(); it != m.end(); it++) { cout<<it->first<<"\t"<<it->second<<endl; } } void test01 () { map<int, int> m; m.insert(make_pair(1, 10)); m.insert(make_pair(4, 40)); m.insert(make_pair(3, 30)); m.insert(make_pair(2, 20)); printMap(m); cout<<endl; map<int, int> m2(m); printMap(m2); cout<<endl; map<int, int> m3; m3 = m2; printMap(m3); } int main() { test01(); return 0; } 1 10 2 20 3 30 4 40 1 10 2 20 3 30 4 40 1 10 2 20 3 30 4 40

map的大小和交换

map插入和删除

void test02() { map<int, int> m; // 第一种 m.insert(pair<int, int>(1, 10)); //第二种 m.insert(make_pair(2,20)); //第三种 m.insert(map<int, int>::value_type(3, 30)); //第四种 m[4] = 40; printMap(m); cout<<endl<<m[5]<<endl<<endl; printMap(m); } 1 10 2 20 3 30 4 40 0 1 10 2 20 3 30 4 40 5 0 Program ended with exit code: 0

不建议用第四种中括号的方式插入

如果没找到key为5的值, 他会自动创建一个(5, 0)的组对插入

可以用中括号获取key对应的value的值

insert() 函数也返回一个pair组队, 第一个元素是插入成功的key值, 第二个是bool

查找和统计

void test02() { map<int, int> m; // 第一种 m.insert(pair<int, int>(1, 10)); //第二种 m.insert(make_pair(2,20)); //第三种 pair<map<int, int>::iterator, bool> it = m.insert(map<int, int>::value_type(3, 30)); // 返回一个组队, 第一个是map中键值对元素, 第二个是bool cout<<(it.first)->second<<endl; //第四种 m[4] = 40; // 查找 auto it2 = m.find(3); if (it2 == m.end()) cout<<"no"<<endl; else cout<<"key: "<<it2->first<<"\tvalue: "<<(*it2).second<<endl; // 计数 unsigned long num = m.count(2); cout<<"num: "<<num<<endl; } 30 key: 3 value: 30 num: 1 map的count只能是0或1, 后面的相同key的插入不进去multimap的count函数才可能大于1

map排序

利用仿函数, 改变map排序规则 , 但是只能根据键值排序即使map存的是键值对, 仿函数仍然是两个参数, 传入的两个键值

内置数据类型

class MyCompare { public: bool operator() (int v1, int v2) const { return v1 > v2; } }; void test03() { map<int, int, MyCompare> m; m.insert(make_pair(1, 50)); m.insert(make_pair(2, 40)); m.insert(make_pair(3, 30)); m.insert(make_pair(4, 20)); m.insert(make_pair(5, 10)); for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) { cout<<"key: "<<it->first<<"\tvalue: "<<it->second<<endl; } }

自定义数据类型

class MyCompare { public: bool operator() (Person p1, Person p2) const { return p1.age > p2.age; } }; void test03() { map<Person, int, MyCompare> m; m.insert(make_pair(Person("y", 1), 50)); m.insert(make_pair(Person("yy", 2), 40)); m.insert(make_pair(Person("yyy", 3), 30)); m.insert(make_pair(Person("yyyy", 4), 20)); m.insert(make_pair(Person("yyyyy", 5), 10)); for (map<Person, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) { cout<<"key: \nname: "<<it->first.name<<" age: "<<it->first.age<<"\nvalue: "<<it->second<<endl; } }

STL案例–员工分组

#include <iostream> #include <string> #include <vector> #include <map> #include <ctime> using namespace std; #define CEHUA 0 #define XUANCHUAN 1 #define YANFA 2 class Worker { public: string name; int salary; }; void createWorkers(vector<Worker>& vWorker) { string nameSeed = "ABCDEFGHIJ"; for (int i = 0; i < 10; i++) { Worker w; w.name = "员工"; w.name += nameSeed[i]; w.salary = rand() % 10001 + 10000; vWorker.push_back(w); } } void getGroup(vector<Worker>& w, multimap<int, Worker>& m) { string nameSeed = "ABCDEFGHIJ"; for (int i = 0; i < 10; i++) { int num = rand() % 3 + 1; m.insert(make_pair(num, w[i])); } } void showWorkers(multimap<int, Worker>& m) { cout<<"策划: "<<endl; multimap<int, Worker>::iterator pos = m.find(CEHUA); unsigned long num = m.count(CEHUA); int index = 0; for (;pos != m.end() && index < num; pos++, index++) { cout<<pos->second.name<<"\t"<<(*pos).second.salary<<endl; } cout<<"---------------------------"<<endl; cout<<"宣传: "<<endl; pos = m.find(YANFA); num = m.count(YANFA); index = 0; for (;pos != m.end() && index < num; pos++, index++) { cout<<pos->second.name<<"\t"<<(*pos).second.salary<<endl; } cout<<"---------------------------"<<endl; cout<<"研发: "<<endl; pos = m.find(XUANCHUAN); num = m.count(XUANCHUAN); index = 0; for (;pos != m.end() && index < num; pos++, index++) { cout<<pos->second.name<<"\t"<<(*pos).second.salary<<endl; } cout<<endl; } int main() { srand((unsigned int)time(NULL)); vector<Worker> vWorker; createWorkers(vWorker); multimap<int, Worker> m; getGroup(vWorker, m); showWorkers(m); return 0; }
最新回复(0)