zoukankan      html  css  js  c++  java
  • 第十一章 关联容器

    11.1

    map:存储关键字-值(key-value)对的容器,关键字起到索引的作用,值则表示与索引相关联的数据;关键字是唯一、有序存储的

    vector:存储单一类型元素的容器;元素是按添加顺序存储的

    11.2

    list:频繁在任意处插入/删除元素但不要求有随机访问能力时

    vector:在尾部插入/删除元素且要求具有随机访问能力时

    deque:在首尾插入/删除元素且要求具有随机访问能力时

    map:统计每个单词在输入中出现的次数

    set:查找集合中是否包含某个数

    11.3

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15  
    16 using namespace std;
    17 using namespace std::placeholders;
    18 
    19 int main()
    20 {
    21        map<string, int> jzd;
    22        string word;
    23        while (cin >> word) {
    24            ++jzd[word];
    25        }
    26        for (auto &i : jzd) {
    27            cout << i.first << " occurs about " << i.second << (i.second > 1 ? "times.
    " : "time
    "); 
    28        }
    29     return 0;
    30 }
    View Code

    11.4

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 int main()
    21 {
    22        map<string, int> jzd;
    23        string word;
    24        while (cin >> word) {
    25            for (auto &i : word)
    26             if (i <= 'Z' && i >= 'A')    i = tolower(i);
    27         for (auto it = word.begin(); it != word.end(); ++it) {
    28             if (ispunct(*it)) {
    29                 it = word.erase(it);
    30                 --it;
    31             }
    32         }
    33            ++jzd[word];
    34        }
    35        for (auto &i : jzd) {
    36            cout << i.first << " occurs about " << i.second << (i.second > 1 ? "times.
    " : "time
    "); 
    37        }
    38     return 0;
    39 }
    View Code 

     

    11.5

    map:每个元素都是一个关键字-值对,初始化时必须提供关键字类型和值类型

    set:每个元素只是一个关键字,没有值,元素类型就是关键字类型

    11.6

    set:元素都是唯一有序的

    list:插入/删除元素很方便

    11.7

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 int main()
    21 {
    22        map<string, vector<string>> imap;
    23        string name1, name2;
    24        while (cin >> name1) {
    25            cin >> name2;
    26            imap[name1].push_back(name2);
    27        }
    28        for (auto &i : imap) {
    29            for (auto &j : i.second) {
    30                cout << i.first << " " << j << endl;
    31            }
    32            cout << endl;
    33        }
    34     return 0;
    35 }
    View Code

    11.8

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 void use_set(const vector<string> &vec)
    21 {
    22     set<string> iset(vec.begin(), vec.end());
    23     for (auto &i : iset)    cout << i << " ";
    24     cout << endl;
    25 }
    26 
    27 void use_vector(const vector<string> &vec)
    28 {
    29     vector<string> ivec(vec.begin(), vec.end());
    30     //unique必须要先sort过 
    31     sort(ivec.begin(), ivec.end());
    32     vector<string>::iterator it = unique(ivec.begin(), ivec.end());
    33     ivec.erase(it, ivec.end());
    34     for (auto &i : ivec)    cout << i << " ";
    35     cout << endl;
    36 }
    37 
    38 int main()
    39 {
    40     vector<string> vec = {"scout", "peanut", "jack", "peanut", "amazon", "jack", "demo"};
    41        use_set(vec);
    42        use_vector(vec);
    43     return 0;
    44 }
    View Code

    11.9

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 int main()
    21 {
    22     map<string, list<int>> imap;
    23     imap = {{"kzw", {2, 3, 5}}, {"ly", {1, 4, 6}}};
    24     for (auto &i : imap) {
    25         for (auto &j : i.second) {
    26             cout << i.first << " occurs at line " << j << endl; 
    27         }
    28     }
    29     return 0;
    30 }
    View Code

    11.10

    可以定义一个 vector<int>::iterator 到 int 的map,因为容器vector的迭代器定义了行为正常的<运算符。

    而list的迭代器则没有定义大小比较的操作。

    11.11

    	bool (*pf)(const Sales_data &, const Sales_data &) = compareIsbn;
    	multiset<Sales_data, pf> bookstore(compareIsbn);
    

     

    11.12

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 int main()
    21 {
    22     vector<pair<string, int>> vec;
    23     pair<string, int> pa;
    24     string ss;
    25     int i;
    26     while (cin >> ss >> i) {
    27         pa.first = ss;
    28         pa.second = i;
    29         vec.push_back(pa);
    30     }
    31     for (auto &i : vec) {
    32         cout << i.first << " " << i.second << endl;
    33     }
    34     return 0;
    35 }
    View Code

    11.13

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 void func1()
    21 {
    22     vector<pair<string, int>> vec;
    23     pair<string, int> pa;
    24     string ss;
    25     int i;
    26     while (cin >> ss >> i) {
    27         pa.first = ss;
    28         pa.second = i;
    29         vec.push_back(pa);
    30     }    
    31 }
    32 
    33 void func2()
    34 {
    35     vector<pair<string, int>> vec;
    36     string ss;
    37     int i;
    38     while (cin >> ss >> i) {
    39         pair<string, int> pa(ss, i);
    40         vec.push_back(pa);
    41     }
    42 }
    43 
    44 void func3()
    45 {
    46     vector<pair<string, int>> vec;
    47     string ss;
    48     int i;
    49     while (cin >> ss >> i) {
    50         pair<string, int> pa = {ss, i};
    51         vec.push_back(pa);
    52     }
    53 }
    54 
    55 void func4()
    56 {
    57     vector<pair<string, int>> vec;
    58     string ss;
    59     int i;
    60     while (cin >> ss >> i) {
    61         pair<string, int> pa{ss, i};
    62         vec.push_back(pa);
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     func1();
    69     func2();
    70     func3();
    71     func4();
    72     return 0;
    73 }
    View Code

    11.14

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <stack>
    10 #include <queue>
    11 #include <algorithm> 
    12 #include <functional>
    13 #include <map>
    14 #include <set> 
    15 #include <cctype>
    16  
    17 using namespace std;
    18 using namespace std::placeholders;
    19 
    20 int main()
    21 {
    22        map<string, vector<pair<string, string>>> imap;
    23        string name1, name2, birthday;
    24        while (cin >> name1) {
    25            cin >> name2 >> birthday;
    26            pair<string, string> pa(name2, birthday);
    27            imap[name1].push_back(pa);
    28        }
    29        for (auto &i : imap) {
    30            for (auto &j : i.second) {
    31                cout << i.first << " " << j.first << " " << j.second << endl;
    32            }
    33            cout << endl;
    34        }
    35     return 0;
    36 }
    View Code

    11.15

    mapped_type:vector<int>

    key_type:int

    value_type:pair<int, vector<int>>

    11.16

        map<string, int> imap = {{"cat", 2}, {"demo", 3}};
    	map<string, int>::iterator map_it = imap.begin();
    	int a = map_it->second; 
    	cout << a << endl;

    11.17

    第二个错误,因为关联容器不支持push_back()

    11.18

    	map<string, int>::const_iterator map_it = word_count.cbegin();

    11.19

    多个方法:

    	//way1
    	bool (*pf)(const Sales_data &, const Sales_data &) = compareIsbn;
    	multiset<Sales_data, pf> bookstore(compareIsbn); 
    	multiset<Sales_data, pf>::iterator it = bookstore.begin();
    	//way2
    	multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)> bookstore(compareIsbn);  
    	multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)>::iterator it = bookstore.begin(); 
        //way3
        using compareType = bool (*)(const Sales_data &lhs, const Sales_data &rhs);  
    	multiset<Sales_data, compareType> bookstore(compareIsbn);  
    	multiset<Sales_data, compareType>::iterator it = bookstore.begin();
    

    11.20

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <array>
    10 #include <stack>
    11 #include <queue>
    12 #include <algorithm> 
    13 #include <functional>
    14 #include <map>
    15 #include <set> 
    16 #include <cctype>
    17  
    18 using namespace std;
    19 using namespace std::placeholders;
    20 
    21 int main()
    22 {
    23     map<string, size_t> imap;
    24     string word;
    25     while (cin >> word) {
    26         //retPair的类型为pair<map<string, size_t>::iterator, bool>
    27         //如果imap中存在关键字为word的元素,则insert什么也不做 
    28         auto retPair = imap.insert(make_pair(word, 1));
    29         if (retPair.second == false)
    30             ++retPair.first->second;
    31     }
    32     return 0;
    33 }
    View Code

    显然下标运算符那个版本更容易编写,因为map的下标运算符可以:①若map中无对应元素,下标运算符可以插入该元素到map中;②若map中有对应元素,则由于下标运算符返回一个左值,故可以将map的mapped_type对象自加。

    11.21

    • word_count.insert({word, 0}):返回一个pair<map<string, size_t>::iterator, bool>,即向word_count中插入一个pair<word, 0>(含有该关键字的元素已存在的话就不做任何事情);
    • 然后解引用该元素(即map<string, size_t>::iterator->),得到word_count中的pair<word, 0>或pair<word, n>(对应已存在的情况),再将第二成员的值自加。

      综上:作用是单词计数(尚未存在于map中的单词记录其中且其计数器初始化为1,已存在的仅仅将其计数器加一)

    11.22

    	map<string, vector<int>> imap;
    	string word;
    	vector<int> vec;
    	//参数类型以及返回类型 
    	pair<map<string, vector<int>>::iterator, bool> retPair = imap.insert(make_pair(word, vec));

    参数类型:make_pair(word, vec)

    返回类型:pair<map<string, vector<int>>::iterator, bool>

    11.23

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <array>
    10 #include <stack>
    11 #include <queue>
    12 #include <algorithm> 
    13 #include <functional>
    14 #include <map>
    15 #include <set> 
    16 #include <cctype>
    17  
    18 using namespace std;
    19 using namespace std::placeholders;
    20 
    21 int main()
    22 {
    23     multimap<string, string> mimap;
    24     string name1, name2;
    25     while (cin >> name1 >> name2)
    26         mimap.insert(make_pair(name1, name2));
    27     for (auto &i : mimap)
    28         cout << i.first << " " << i.second << endl;
    29     return 0;
    30 }
    View Code

    11.24

    插入元素pair<0, 1>到 m 中

    11.25

    v是一个空容器,vector的下标运算符不可以插入元素,故本题是对一个未知的内存空间赋值,会导致运行时错误;

    而map的下标运算符支持插入元素,故上题是可行的。

    11.26

    用什么类型来对一个 map 进行下标操作:key_type

    下标运算符返回的类型:mapped_type

    	map<string, vector<int>> imap;
    	vector<int> vec = {65, 66, 67, 68, 69};
    	string s = "A-E's ASCII";
    	imap[s] = vec;		//第一个类型的实例是s,第二个类型的实例是vec 
    

    11.27

    使用count:统计容器中关键字等于 k 的元素的数量,大多用于multimap或multiset

    使用find:查找某个元素是否在容器中

    11.28

    	map<string, vector<int>> imap;
    	string s;
    	map<string, vector<int>>::iterator it = imap.find(s); 
    

    11.29

    如果给定的关键字不在容器中,

    upper_bound:返回一个迭代器,该迭代器指向一个不影响容器中元素顺序的关键字插入位置(但不插入)

    lower_bound:返回一个迭代器,该迭代器指向一个不影响排序的关键字插入位置(但不插入)

    equal_range:返回一个迭代器pair,该pair中的两个迭代器都指向关键字可以插入的位置(但不插入)

    11.30

    pos.first:pos为一个pair<multimap<string, string>::iterator, multimap<string, string>::iterator>,故得到pair的第一个成员,是一个multimap迭代器,指向第一个匹配的元素;

    pos.first->:解引用此迭代器,提取multimap中的元素,该元素是一个pair<string, string>;

    pos.first->second:multimap中元素的题目部分

    11.31

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <array>
    10 #include <stack>
    11 #include <queue>
    12 #include <algorithm> 
    13 #include <functional>
    14 #include <map>
    15 #include <set> 
    16 #include <cctype>
    17  
    18 using namespace std;
    19 using namespace std::placeholders;
    20 
    21 int main()
    22 {
    23     multimap<string, string> mimap;
    24     string name1, name2;
    25     while (cin >> name1) {
    26         if (name1 == "eof") 
    27             break;
    28         cin >> name2;
    29         mimap.insert(make_pair(name1, name2));
    30     }
    31     cout << "请输入要删除作品的作者:";
    32     cin >> name1;
    33     auto it = mimap.find(name1);
    34     if (it != mimap.end()) {
    35         cout << "请输入要删除的作品名:";
    36         cin >> name2;
    37         auto mit = mimap.upper_bound(name1);
    38         while (it != mit) {
    39             if (it->second == name2) {
    40                 mimap.erase(it);
    41                 --it;
    42                 break;
    43             }
    44             ++it;
    45         } 
    46         if (it == mit)    cout << "该作者没有此书!
    ";
    47         else {
    48             for (auto &i : mimap) {
    49                 cout << "作者:" << i.first << " 书名:" <<  i.second << endl; 
    50             }
    51         }
    52     }
    53     else {
    54         cout << "查无此作者!
    ";
    55     }
    56     return 0;
    57 }
    View Code

    11.32

     1 #include <iostream>
     2 #include <fstream>
     3 #include <iterator>
     4 #include <vector> 
     5 #include <string>
     6 #include <deque>
     7 #include <list> 
     8 #include <forward_list>
     9 #include <array>
    10 #include <stack>
    11 #include <queue>
    12 #include <algorithm> 
    13 #include <functional>
    14 #include <map>
    15 #include <set> 
    16 #include <cctype>
    17  
    18 using namespace std;
    19 using namespace std::placeholders;
    20 
    21 int main()
    22 {
    23     multimap<string, string> mimap;
    24     string name1, name2;
    25     while (cin >> name1) {
    26         if (name1 == "eof") 
    27             break;
    28         cin >> name2;
    29         mimap.insert(make_pair(name1, name2));
    30     }
    31     for (auto &i : mimap)
    32         cout << "作者:" << i.first << " 书名:" <<  i.second << endl; 
    33     return 0;
    34 }
    View Code

     

    11.33

     1 #include <iostream>
     2 #include <fstream>
     3 #include <sstream>
     4 #include <iterator>
     5 #include <vector> 
     6 #include <string>
     7 #include <deque>
     8 #include <list> 
     9 #include <forward_list>
    10 #include <array>
    11 #include <stack>
    12 #include <queue>
    13 #include <algorithm> 
    14 #include <functional>
    15 #include <map>
    16 #include <set> 
    17 #include <cctype>
    18  
    19 using namespace std;
    20 using namespace std::placeholders;
    21 
    22 const string &transform(const string &s, const map<string, string> &imap)
    23 {
    24     auto it = imap.find(s);
    25     if (it != imap.end()) {
    26         return it->second;
    27     }
    28     else
    29         return s;
    30 }
    31 
    32 void word_transform(ifstream &rin, ifstream &tin)
    33 {
    34     map<string, string> imap;
    35     string s1, s2;
    36     while (rin >> s1 && getline(rin, s2)) {
    37         s2 = s2.substr(1);
    38         imap.insert(make_pair(s1, s2));
    39     }
    40     string word, line;
    41     while (getline(tin, line)) {
    42         istringstream in(line);
    43         bool space = false;
    44         while (in >> word) {
    45             if (!space)
    46                 space = true;
    47             else 
    48                 cout << " ";
    49             cout << transform(word, imap);
    50         }
    51         cout << endl;
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     ifstream rin("map_file.txt"), tin("data.txt");
    58     word_transform(rin, tin);  
    59     return 0;
    60 }
    View Code

    11.34

    传递的map对象是const的,而下标运算可能会在map中插入新元素,这与形参相悖;此外,用下标运算或者返回指定关键字对应的值(即mapped_type),或者添加一个指定关键字的元素(并对其进行值初始化),那么如果是添加元素的话,结果是返回空串,这与目的相悖。

    const string &transform(const string &s, map<string, string> &imap)
    {	
    	//下标返回一个mapped_type对象 
    	string transAfter = imap[s];
    	//若插入元素的话,会返回空串 
    	return imap[s];
    }
    

    11.35

    给map对象添加元素时,如果其中已存在与欲添加元素具有相同关键字的元素,那么编译器将忽略此次添加操作。

    11.36

    当只有一个关键字和空格时:key会读取关键字,这一行只剩下空格可以读取到value中;因此value只有一个空格,即size为1,从而 if 条件不成立,转交给 else,所以会触发异常:throw runtime_error("no rule for "+key);

    11.37

    与有序容器相比的优势:关键字类型不必要有明显的排序关系,而且省去了维护元素的序代价;

    有序容器的优势:元素有序排放

    11.38

    单词计数:

    int main()
    {
        unordered_map<string, int> umap;
        string word;
        while (cin >> word) {
        	++umap[word];
        }
    	return 0;
    }
    

    单词转换:

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <iterator>
    #include <vector> 
    #include <string>
    #include <deque>
    #include <list> 
    #include <forward_list>
    #include <array>
    #include <stack>
    #include <queue>
    #include <algorithm> 
    #include <functional>
    #include <map>
    #include <set> 
    #include <cctype>
    #include <unordered_map>
    #include <unordered_set>
     
    using namespace std;
    using namespace std::placeholders;
    
    const string &transform(const string &s, const unordered_map<string, string> &imap)	//修改处2 
    {
    	auto it = imap.find(s);
    	if (it != imap.end()) {
    		return it->second;
    	}
    	else
    		return s;
    }
    
    void word_transform(ifstream &rin, ifstream &tin)
    {
    	unordered_map<string, string> imap;	//修改处1 
    	string s1, s2;
    	while (rin >> s1 && getline(rin, s2)) {
    		s2 = s2.substr(1);
    		imap.insert(make_pair(s1, s2));
    	}
    	string word, line;
    	while (getline(tin, line)) {
    		istringstream in(line);
    		bool space = false;
    		while (in >> word) {
    			if (!space)
    				space = true;
    			else 
    				cout << " ";
    			cout << transform(word, imap);
    		}
    		cout << endl;
    	}
    }
    
    int main()
    {
    	ifstream rin("map_file.txt"), tin("data.txt");
    	word_transform(rin, tin);  
    	return 0;
    }
    
  • 相关阅读:
    剑指offer 51.构建乘积数组
    剑指offer 50.数组中重复的数字
    股票价格涨跌预测—基于KNN分类器
    R语言-神经网络包RSNNS
    基于客户保持率的人口特性分析
    车辆碰撞位置间的关联性分析
    统计学的七大支柱[转载@谢益辉]
    AutoDesK演示项目部署
    自定义数字键盘组件化方案
    2020年大前端发展趋势
  • 原文地址:https://www.cnblogs.com/xzxl/p/7701246.html
Copyright © 2011-2022 走看看