c++基础——关联容器
Posted konghuzi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++基础——关联容器相关的知识,希望对你有一定的参考价值。
1.关联容器
关联容器中的元素时按照关键字来保存和访问的,与之相对的,顺序容器中的元素时按它们在容器中的位置来顺序保存和访问的。两个主要关联容器是 map 和 set。标准库提供了8个关联容器,这8个容器间的不同体现在
三个维度上:
- 或是一个 map 或是一个 set
- 或者要求不重复关键字,或者允许重复关键字
- 按顺序保存元素,或无序保存
2.使用关联容器
- map
-
1 //统计每个单词在输入中出现的次数 2 map<string, size_t> word_count; //string到size_t的空map 3 string word; 4 while (cin >> word) 5 ++word_count[word]; //提取word的计数器并将其加1 6 for(const auto &w : word_count) //对map中的每个元素 7 //打印结果 8 cout << w.first << " occurs " << w.second 9 << ((w.second > 1)? " times ": "time") << endl;
- set
-
1 //统计输入中每个单词出现的次数 2 map<string, size_t> word_count; //string到size_t的空map 3 set<string> exclude = "The", "But", "And", "Or", "An", "A", 4 "the", "but", "and", "or", "an", "a"; 5 string word; 6 while (cin >> word) 7 //只统计不在exclude中的单词 8 if (exclude.find(word) == exclude.end()) 9 ++word_count[word]; //获取并递增word的计数器
3.关联容器概述
关联容器不支持顺序容器的位置相关操作,例如push_front或push_back。原因是关联容器中元素是根据关键字存储的,这些操作对关联容器没有意义。关联容器的迭代器都是双向的。
- 初始化 multimap 和 multiset。一个map或set中的关键字必须是唯一的,容器multimap和multiset没有此限制,它们允许多个元素具有相同的关键字。
-
1 //定义一个有20个元素的vector,保存0到9每个整数的两个拷贝 2 vector<int> ivec; 3 for (vector<int>::size_type i = 0; i != 10; ++i) 4 ivec.push_back(i); 5 ivec.push_back(i); //每个数重复保存一次 6 7 //iset包含来自ivec的不重复的元素,miset包含所有20个元素 8 set<int> iset(ivec.begin(), ivec.end()); 9 multiset<int> miset(ivec.begin(), ivec.end()); 10 cout << ivec.size() << endl; //打印出20 11 cout << iset.size() << endl; //打印出10 12 cout << miset.size() << endl; //打印出20
3.1 set,map自定义函数排序
关联容器对其关键字类型有一些限制。对于有序容器,关键字类型必须定义元素比较的方法。默认情况下,标准库使用关键字类型<运算符来比较两个关键字。
用来组织一个容器中元素的操作的类型也是该容器类型的一部分。为了指定使用自定义的操作,必须在定义关联容器类型时提供此操作的类型。使用方法如下:用尖括号指定要定义的那种类型的容器,自定义的操作类型必须在尖括号中紧跟元素类型给出。例如:我们不能直接定义一个Sales_data的multiset,因为Sales_data没有<运算符。因此需要定义一个compareIsbn:
1 bool compareIsbn (const Sales_data &lhs, const Sales_data &rhs) 2 3 return lhs.isbn() < rhs.isbn(); 4
为了使用自己定义的操作,在定义multiset时我们必须提供两个类型:关键字类型Sales_data,以及比较操作类型——应该是一种函数指针类型,可以指向compareIsbn。
1 //bookstore中多条记录可以有相同的ISBN 2 //bookstore中的元素以ISBN的顺序进行排列 3 multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
此处,我们使用decltype来指出自定义操作的类型。记住,当用decltype来获得一个函数指针类型时,必须加上一个*来指出我们要使用一个给定函数类型的指针;用compareIsbn来初始化bookstore对象,这表示当我们想bookstore添加元素时,通过调用compareIsbn来为这些元素排序。
下面举两个实例:均按照降序进行排列,容器默认是使用“<”。
1 #include <set> 2 #include <map> 3 #include <vector> 4 #include <string> 5 #include <iostream> 6 using namespace std; 7 8 class st 9 public: 10 int id; 11 string name; 12 st(int id, string name); 13 ~st() ; 14 ; 15 16 st::st(int id, string name) :id(id), name(name) 17 18 19 20 bool compareST(const int &s, const int &r) 21 return s > r; 22 23 24 bool compareST2(const st *s, const st *r) 25 return s->id > r->id; 26 27 28 int main() 29 30 /// map 31 st *st1 = new st(3, "st1"); 32 st *st2 = new st(1, "st2"); 33 st *st3 = new st(2, "st3"); 34 35 map<int, st*, decltype(compareST)*> temp(compareST); 36 temp.insert(make_pair(st1->id, st1)); 37 temp.insert(make_pair(st2->id, st2)); 38 temp.insert(make_pair(st3->id, st3)); 39 40 for (auto item : temp) 41 cout << item.first << "\\t" << item.second->name << endl; 42 43 44 cout << "========================" << "\\n"; 45 46 /// set 47 set<st*, decltype(compareST2)*> temp2(compareST2); 48 temp2.insert(st1); 49 temp2.insert(st2); 50 temp2.insert(st3); 51 52 for (auto item : temp2) 53 cout << item->id << "\\t" << item->name << endl; 54 55 56 getchar(); 57 return 0; 58
以上是关于c++基础——关联容器的主要内容,如果未能解决你的问题,请参考以下文章