笔记:C++学习之旅---关联容器
 笔记:C++学习之旅---关联容器
 
       关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。
 
       关联容器支持高效的关键字查找和访问。两个主要的关联容器类是map和set。
 
 map中的元素是一些关键字的-值(key-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字:set支持高效的关键字查询操作--检查一个给定关键字是否在set中。
 
 例子:
 
 一个经典的使用关联数组的例子是单词计数程序:
 
 #include 
 <iostream>
 
 #include 
 <string>
 
 #include 
 <map>
 
 #include 
 <set>
 
 using 
 namespace 
 std;
 
 int 
 main()
 
 {
 
              
 map
 < 
 string
 , 
 size_t
 > word_count;
 
              
 string 
 word;
 
              
 set
 < 
 string
 > exclude = { 
 "The"
 , 
 "But" 
 , 
 "And" 
 , 
 "Or" 
 , 
 "An" 
 , 
 "A" 
 , 
 "the" 
 , 
 "but" 
 , 
 "and" 
 , 
 "or"
 , 
 "an" 
 , 
 "a" 
 };
 //忽略的单词
 
             cout << 
 "请输入一串英文单词\n" 
 ;
 
              
 while 
 (cin >> word)
 
             {
 
                          
 if 
 (word == 
 "#"
 )
 
                                      
 break
 ;
 
                          
 if 
 (exclude.find(word) == exclude.end())
 
                         {
 
                                     ++word_count[word];
 
                         }
 
             }
 
                          
 for 
 ( 
 const 
 auto 
 &w : word_count)
 
                         cout << w.first << 
 " occurs " 
 << w.second << ((w.second > 1) ? 
 " times " 
 : 
 " time "
 ) << endl;
 
              
 return 
 0;
 
 }
 
 练习11.3 11.4:
 
 编写你自己的单词计数程序,忽略大小写和标点。如,"example"“example,”和“Example”应该递增相同的计数器。
 
 #include 
 <iostream>
 
 #include 
 <map>
 
 #include 
 <string>
 
 #include 
 <algorithm>
 
 using 
 namespace 
 std;
 
 void 
 print(
 map 
 <
 string 
 , 
 size_t 
 > &
 map 
 )
 
 {
 
              
 for 
 ( 
 auto 
 &m : map)
 
                         cout <<m.first<< 
 ":"
 <<m.second<<endl;
 
 }
 
 void 
 word_count_pro(
 map 
 <
 string 
 ,
 size_t 
 > &
 m 
 )
 
 {
 
              
 string 
 word;
 
             cout << 
 "请输入一串英文单词\n" 
 ;
 
              
 while 
 (cin >> word)
 
             {
 
                          
 if 
 (word == 
 "#"
 )
 
                                      
 break
 ;
 
                          
 for 
 ( 
 auto 
 &ch : word)
 
                                     ch = towlower(ch); 
 //大小写转换;
 
                         word.erase(remove_if(word.begin(), word.end(), ispunct), word.end());
 //ispunct 判断是否为标点符号或者特殊字符进行删除;
 
                         ++ 
 m
 [word];
 
             }
 
             print( 
 m
 );
 
 }
 
 int 
 main()
 
 {
 
              
 map
 < 
 string
 , 
 size_t
 > map;
 
             word_count_pro(map);
 
              
 return 
 0;
 
 }
 
 关联容器的概述
 
  #include 
  <iostream>
 
 
 
  #include 
  <vector>
 
 
 
  #include 
  <map>
 
 
 
  #include 
  <set>
 
 
 
  using 
  namespace 
  std;
 
 
 
  int 
  main()
 
 
 
  {
 
 
 
               
  vector
  < 
  int
  > vec;
 
 
 
               
  for 
  ( 
  vector
  < 
  int
  >:: 
  size_type 
  i = 0; i != 10; ++i)
 
 
 
              {
 
 
 
                          vec.push_back(i);
 
 
 
                          vec.push_back(i);
 
 
 
              }
 
 
 
               
  set
  < 
  int
  > iset(vec.cbegin(), vec.cend());
 
 
 
               
  multiset
  < 
  int
  > miset(vec.cbegin(), vec.cend());
 
 
 
              cout << vec.size() << endl; 
  //20
 
 
 
              cout << iset.size() << endl; 
  //10
 
 
 
              cout << miset.size() << endl; 
  //20
 
 
 
               
  return 
  0;
 
 
 }
 
 练习11.7:
 
 定义一个map,关键字是家庭的姓,值是一个vector,保存家中孩子(们)的名。编写代码,实现添加新的家庭以及向已有家庭中添加新的孩子。
 
  #include 
  <iostream>
 
 
 
  #include 
  <vector>
 
 
 
  #include 
  <string>
 
 
 
  #include 
  <map>
 
 
 
  using 
  namespace 
  std;
 
 
 
  void 
  print(
  multimap 
  <
  string 
  , 
  vector 
  <
  string 
  >> &
  family
  )
 
 
 
  {
 
 
              
 //按照英文名称习惯打印名字,如Tom.Green
 
              
 for 
 ( 
 auto 
 &member : famil
 y
 )
 
              {
 
 
 
                          cout << 
  "Mumber is:" 
  << 
  " " 
  << endl;
 
 
 
                           
  for 
  ( 
  auto 
  it = member.second.begin(); it != member.second.end(); ++it)
 
 
 
                          {
 
 
 
                                      cout << *it << 
  "." 
  << member.first << endl;
 
 
 
                          }
 
 
 
                          cout << endl;
 
 
 
              }
 
 
 
  }
 
 
 
  int 
  main()
 
 
 
  {
 
 
 
               
  string 
  fname = 
  ""
  , name = 
  ""
  ;
 
 
 
               
  vector
  < 
  string
  > vec = { 
  "Tom"
  , 
  "Jerry" 
  , 
  "Lucy" 
  };
 
 
 
               
  multimap
  < 
  string
  , 
  vector
  < 
  string
  >> family = { { 
  "Green"
  , vec }, { 
  "white" 
  , vec } };
 
 
 
              print(family); 
  //打印结果
 
 
 
               
  //先输入family name,然后自己name
 
 
 
               
  //while (cin >> fname >> name)
 
 
 
               
  //family[fname].push_back(name);
 
 
 
               
  //修改地方,先输入名,再输入姓,可以重复保存了,所以不像上面那样来插入名字
 
 
 
              cout << 
  "请输入你的名:\n" 
  ;
 
 
 
               
  while 
  (cin >> fname)
 
 
 
              {
 
 
 
                           
  vector
  < 
  string
  > vec;
 
 
 
                          cout << 
  "请输入你的性(输入end退出):\n" 
  ;
 
 
 
                           
  while 
  (cin >> name && name != 
  "end"
  )
  //以end结束输入
 
 
 
                          {
 
 
 
                                      vec.push_back(name);
 
 
 
                          }
 
 
 
                                      family.insert({fname,vec }); 
  //将姓插入到名前面
 
 
 
                                       
  //添加新家庭后再次打印
 
 
 
                                      print(family);
 
 
             }
      
 
               
  return 
  0;
 
 
 }
 
 pair类型
 
 类似容器,pair是一个用来生成特定类型的模版。与其他标准库类型不同,pair的数据成员public的两个成员分别命名为first和second。
 
 关联容器的操作
 
 向map中添加元素
 
 对于一个map进行insert操作时,必须记住元素类型是pair。
 
 练习11.20:
 
 重写单词计数程序,使用insert代替下标操作。你认为哪个程序更容易编写和阅读
 
  #include 
  <iostream>
 
 
 
  #include 
  <vector>
 
 
 
  #include 
  <map>
 
 
 
  #include 
  <string>
 
 
 
  using 
  namespace 
  std;
 
 
 
  int 
  main()
 
 
 
  {
 
 
 
               
  map
  < 
  string
  , 
  size_t
  > word_count;
 
 
 
               
  string 
  word;
 
 
 
              cout << 
  "请输入一串字符串\n" 
  ;
 
 
 
               
  while 
  (cin >> word)
 
 
 
              {
 
 
 
                           
  if 
  (word == 
  "#"
  )
 
 
 
                                       
  break
  ;
 
 
 
                           
  auto 
  ret = word_count.insert({ word, 1 });//创建一个pair
 
 
 
                           
  if 
  (!ret.second)
 
 
                         {
 
                                     ++ret.first->second;//map中值部分
 
                          }
 
 
 
              }
 
 
 
               
  for 
  ( 
  auto 
  &w : word_count)
 
 
 
                          cout << w.first << 
  " " 
  << w.second << ((w.second > 1) ? 
  " times " 
  : 
  " time "
  )<<endl;
 
 
 
               
  return 
  0;
 
 
 }
 
 删除元素
 
 练习11.31:
 
 编写程序,定义一个作者及其作品的multimap。使用find在multimap中查找一个元素并用erase删除它。确保你的程序在元素不在map中时也能正常运行。
 
  #include 
  <iostream>
 
 
 
  #include 
  <string>
 
 
 
  #include 
  <map>
 
 
 
  #include 
  <algorithm>
 
 
 
  using 
  namespace 
  std;
 
 
 
  int 
  main()
 
 
 
  {
 
 
 
               
  multimap
  < 
  string
  , 
  string
  > authors{ { 
  "alan"
  , 
  "DMA" 
  }, { 
  "pezy" 
  , 
  "LeetCode" 
  }, { 
  "alan"
  , 
  "CLRS" 
  },
 
 
 
              { 
  "wang"
  , 
  "FTP" 
  }, { 
  "pezy" 
  , 
  "CP5" 
  }, { 
  "wang" 
  , 
  "CPP-Concurrency" 
  } };
 
 
 
              cout << 
  "erase before:\n"
  ;
 
 
 
               
  for 
  ( 
  auto 
  &a : authors)
 
 
 
                          cout << a.first << 
  ":" 
  <<a.second<< endl;
 
 
 
               
  string 
  author = 
  "pezy"
  ;
 
 
 
               
  string 
  work = 
  "CP5"
  ;
 
 
 
               
  auto 
  found = authors.find(author); 
  //找到作者;
 
 
 
               
  auto 
  count = authors.count(author); 
  //记录次数;
 
 
 
               
  while 
  (count)
 
 
 
              {
 
 
 
                           
  if 
  (found->second == work) 
  //找到CP5,然后删除;
 
 
 
                          {
 
 
 
                                      authors.erase(found);
 
 
 
                                       
  break
  ;
 
 
 
                          }
 
 
 
                          ++found;
 
 
 
                          --count;
 
 
 
              }
 
 
 
              cout << 
  "erase after:\n"
  ;
 
 
 
               
  for 
  ( 
  const 
  auto
  & author : authors)
 
 
 
                          cout << author.first << 
  ":" 
  << author.second << std::endl;
 
 
 
               
  return 
  0;
 
 
 }
 
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号