标签:name img ISE occurs push 双向 line mamicode 直接
关联容器中的元素时按照关键字来保存和访问的,与之相对的,顺序容器中的元素时按它们在容器中的位置来顺序保存和访问的。两个主要关联容器是 map 和 set。标准库提供了8个关联容器,这8个容器间的不同体现在
三个维度上:
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;
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的计数器
关联容器不支持顺序容器的位置相关操作,例如push_front或push_back。原因是关联容器中元素是根据关键字存储的,这些操作对关联容器没有意义。关联容器的迭代器都是双向的。
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
关联容器对其关键字类型有一些限制。对于有序容器,关键字类型必须定义元素比较的方法。默认情况下,标准库使用关键字类型<运算符来比较两个关键字。
用来组织一个容器中元素的操作的类型也是该容器类型的一部分。为了指定使用自定义的操作,必须在定义关联容器类型时提供此操作的类型。使用方法如下:用尖括号指定要定义的那种类型的容器,自定义的操作类型必须在尖括号中紧跟元素类型给出。例如:我们不能直接定义一个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 }
标签:name img ISE occurs push 双向 line mamicode 直接
原文地址:https://www.cnblogs.com/KongHuZi/p/11366383.html