第十章 关联容器

 

code:

/*


第十章 关联容器

第10章 关联容器
10.1 引言:pair类型
10.2 关联容器
10.3 map类型
10.4 set类型
10.5 multimap和multiset类型
10.6 容器的综合应用:文本查询程序
小结


第10章 关联容器 305
10.1 引言:pair类型 306
10.2 关联容器 308
10.3 map类型 309
10.3.1 map对象的定义 309
10.3.2 map定义的类型 310
10.3.3 给map添加元素 311
10.3.4 使用下标访问map对象 311
10.3.5 map::insert的使用 313
10.3.6 查找并读取map中的元素 315
10.3.7 从map对象中删除元素 316
10.3.8 map对象的迭代遍历 316
10.3.9 “单词转换”map对象 317
10.4 set类型 319
10.4.1 set容器的定义和使用 319
10.4.2 创建“单词排除”集 321
10.5 multimap和multiset类型 322
10.5.1 元素的添加和删除 322
10.5.2 在multimap和multiset
中查找元素 323
10.6 容器的综合应用:文本查询程序 325
10.6.1 查询程序的设计 326
10.6.2 TextQuery类 327
10.6.3 TextQuery类的使用 328
10.6.4 编写成员函数 330
小结 332
术语 332


*/




//10.1 引言:pair类型-------------------------------------------------------------------------------------------------


//初始化
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
using namespace std;
int main()
{
  pair < string, string > anon; // holds two strings
  pair < string, int > word_count; // holds a string and an int
  pair < string, vector < int >  > line; // holds string and vector<int>
  pair < string, string > author("James", "Joyce");
  typedef pair < string, string > Author;
  Author proust("Marcel", "Proust");
  Author joyce("James", "Joyce");
  return 0;
}


// make_pair
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
using namespace std;
int main()
{
  pair < string, string > next_auth;
  string first, last;
  while(cin >> first >> last)
  {
    // generate a pair from first and last
    next_auth = make_pair(first, last);
    // process next_auth...
  }
  
  return 0;
}




//10.2 关联容器-------------------------------------------------------------------------------------------------


#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
using namespace std;

int main()
{
  typedef map<int,int> CT;
  pair < string, string > next_auth;
  CT c2;         // creates an empty container
  // c2 must be same type as c1
  CT c1(c2);    // copies elements from c2 into c1
  // b and e are iterators denoting a sequence
  CT c(c2.begin(), c2.end());   // copies elements from the sequence into c
  
  return 0;
}



//10.3 map类型-------------------------------------------------------------------------------------------------

// 初始化
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
using namespace std;

int main()
{
  // count number of times each word occurs in the input
  map<string, int> word_count; // empty map from string to int
  map<string, int> word_too(word_count);
  map<string, int> w(word_too.begin(),word_too.end());

  return 0;
}


//迭代器进行解引用将产生 pair 类型的对象

#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <stack>
#include <queue>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map <string, int> word_count; // empty map
  // insert default initialzed element with key Anna; then assign 1 to its value
  word_count["Anna"] = 1;
  
  // get an iterator to an element in word_count
  map < string, int > ::iterator map_it = word_count.begin();
  // *map_it is a reference to a pair<const string, int> object
  cout << map_it->first; // prints the key for this element
  cout << " " << map_it->second; // prints the value of the element
  // map_it->first = "new key"; // error: key is const
  ++map_it->second; // ok: we can change value through an iterator
  return 0;
}


// my test. 
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map <string, int> word_count;
  word_count["Anna"] = 1;
  word_count["Anna"] = 5; // 会覆盖旧值
  
  map < string, int > ::iterator map_it = word_count.begin();
  cout << map_it->first;
  cout << " " << map_it->second;
  ++map_it->second;
  
  cout << endl;
  cout << map_it->first;
  cout << " " << map_it->second;  
  return 0;
}


// test insert
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  pair < string, int > pa=make_pair("Bnna", 5);
  map <string, int> word_count;
  word_count["Anna"] = 1;
  word_count.insert(pa);
  
  map < string, int > ::iterator map_it = word_count.begin();
  cout << map_it->first;
  cout << " " << map_it->second << endl;

  ++map_it;
  cout << map_it->first;
  cout << " " << map_it->second << endl;
  
  return 0;
}


// in book

#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map < string, int > word_count; // empty map
  // insert default initialzed element with key Anna; then assign 1 to its value
  word_count["Anna"] = 1;
  
  cout << word_count["Anna"]; // fetch element indexed by Anna; prints 1
  ++word_count["Anna"]; // fetch the element and add one to it
  cout << word_count["Anna"] << endl; // fetch the element and print it; prints 2
  
  // count number of times each word occurs in the input
  //map < string, int > word_count; // empty map from string to int
  word_count.clear();
  string word;
  while(cin >> word)
    ++word_count[word]; // 输入相同单词,键值加一。map大小不变
  cout << word_count.size() << endl;

  return 0;
}


// my test
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map < string, int > word_count;
  word_count["Anna"] = 1;  
  
  word_count.insert(map<string, int>::value_type("Anna", 2));
  cout << word_count["Anna"] << endl; //1 插入不会改变键值
  
  word_count["Anna"] = 3;  
  cout << word_count["Anna"] << endl; //3 =改变了键值
  
  return 0;
}


// in book
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map < string, int > word_count;
  word_count.insert(make_pair("Anna", 1));
  typedef map<string,int>::value_type valType;
  word_count.insert(valType("Anna", 2));
  cout << word_count["Anna"] << endl;
  
  return 0;
}


// in book
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  // count number of times each word occurs in the input
  map < string, int > word_count; // empty map from string to int
  string word;
  while(cin >> word)
  {
    // inserts element with key equal to word and value 1;
    // if word already in word_count, insert does nothing
    pair < map < string, int > ::iterator, bool > // 返回两个参数:迭代器、bool
      ret = word_count.insert(make_pair(word, 1));
    if(!ret.second)
    // word already in word_count
      ++ret.first->second;
    // increment counter
  }
  return 0;
}


// 修改
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map < string, int > word_count;
  string word;
  typedef map < string, int > ::iterator IT; // typedef
  while(cin >> word)
  {
    pair < IT, bool >   // typedef 简化
      ret = word_count.insert(make_pair(word, 1));
    if(!ret.second)
      ++ret.first->second;
  }
  
  IT it=word_count.begin();
  while( it!=word_count.end() ) {
    cout << it->first << ' ' << it->second << endl;
    ++it;
  }
  
  return 0;
}


// mytest ,可以观察到,如果键不存在,会加入到map中去,默认键值为0
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map<string,int> word_count;
  int occurs = word_count["foobar"];

  typedef map < string, int > ::iterator IT; // typedef  
  IT it=word_count.begin();
  while( it!=word_count.end() ) {
    cout << it->first << ' ' << it->second << endl;
    ++it;
  }
  
  return 0;
}


// count
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map<string,int> word_count;
  word_count["test"]=3;
  
  int occurs = 0;
  if (word_count.count("foobar"))
    occurs = word_count["foobar"];
  
  typedef map < string, int > ::iterator IT; // typedef  
  IT it=word_count.begin();
  while( it!=word_count.end() ) {
    cout << it->first << ' ' << it->second << endl;
    ++it;
  }
  
  return 0;
}


// find
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  typedef map < string, int > ::iterator IT; // typedef  
  map<string,int> word_count;
  word_count["test"]=3;

  int occurs = 0;
  IT it = word_count.find("foobar");
  if (it != word_count.end())
    occurs = it->second;

  cout << occurs << endl;

  return 0;
}


// erase
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map<string,int> word_count;
  word_count["test"]=3;

  // erase of a key returns number of elements removed
  string removal_word("test"); //
  if (word_count.erase(removal_word))
    cout << "ok: " << removal_word << " removed
";
  else
    cout << "oops: " << removal_word << " not found!
";

  return 0;
}


// 遍历。注意输出以键的升序排列。所以,里面应该是堆。。
#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
int main()
{
  map < string, int > word_count;
  word_count["test"] = 3;
  word_count["abc"] = 2;  
  word_count["zzzst"] = 5;  
  
  // get iterator positioned on the first element
  map < string, int > ::const_iterator map_it = word_count.begin();
  // for each element in the map
  while(map_it != word_count.end())
  {
    // print the element key, value pairs
    cout << map_it->first << " occurs " << map_it->second << " times" << endl;
    ++map_it; // increment iterator to denote the next element
  }
  return 0;
}


// in book 单词转换

#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <set>
using namespace std;
/*
 * A program to transform words.
 * Takes two arguments: The first is name of the word transformation file
 *                      The second is name of the input to transform
 */
int main(int argc, char **argv)
{
  // map to hold the word transformation pairs:
  // key is the word to look for in the input; 
  // value is word to use in the output
  map < string, string > trans_map;
  string key, value;
  if(argc != 3)
    throw runtime_error("wrong number of arguments");
  // open transformation file and check that open succeeded
  ifstream map_file;
  if(!open_file(map_file, argv[1]))
    throw runtime_error("no transformation file");
  // read the transformation map and build the map
  while(map_file >> key >> value)
    trans_map.insert(make_pair(key, value));
  // ok, now we're ready to do the transformations
  // open the input file and check that the open succeeded
  ifstream input;
  if(!open_file(input, argv[2]))
    throw runtime_error("no input file");
  string line; // hold each line from the input
  // read the text to transform it a line at a time
  while(getline(input, line))
  {
    istringstream stream(line); // read the line a word at a time
    string word;
    bool firstword = true; // controls whether a space is printed
    while(stream >> word)
    {
      // ok: the actual mapwork, this part is the heart of the program
      map < string, string > ::const_iterator map_it = trans_map.find(word);
      // if this word is in the transformation map
      if(map_it != trans_map.end())
      // replace it by the transformation value in the map
        word = map_it->second;
      if(firstword)
        firstword = false;
      else
        cout << " ";
      // print space between words
      cout << word;
    }
    cout << endl; // done with this line of input
  }
  return 0;
}


// 必定成容易调试的:

#include <iostream>
#include <string>
#include <utility>
#include <map>
#include <sstream>
#include <fstream>
using namespace std;

int main()
{
  map < string, string > trans_map;
  string key, value;
  string ins1("x:\test1.txt"); //输入文件1:对应的单词
  string ins2("x:\test2.txt"); //输入文件2:要转换的句子们
  ifstream inf1(ins1.c_str());  //如不指定路径,把文件放程序文件同一目录下
  ifstream inf2(ins2.c_str());
  
  while(inf1 >> key >> value)   //在文件1中读取一对对数据
    trans_map.insert(make_pair(key, value));  

  string line;
  while(getline(inf2, line))    // 从第2个文件一行行读入
  {
    istringstream stream(line); // 读取的一行字符串,作为输入流
    string word;
    bool firstword = true;      // 控制要不要输出空格。行首无空格
    while(stream >> word)
    {
      // 在map中查找单词
      map < string, string > ::const_iterator map_it = trans_map.find(word);
      if(map_it != trans_map.end()) // 可以找到时,进行转换
        word = map_it->second;  // 木有else,意味着找不到时,不进行转换
      if(firstword)             // 仅第一个单词前,不用空格
        firstword = false;
      else
        cout << " ";            // 其它单词前,用空格
      cout << word;             // 输出单词。用文件读入,屏幕输出
    }
    cout << endl;               // 换行
  }
  
  return 0;
}

/* test1.txt:
'em them
cuz because
gratz grateful
i I
nah no
pos supposed
sez said
tanx thanks
wuz was

*/

/* test2.txt:
nah i sez tanx cuz i wuz pos to
not cuz i wuz gratz

*/

/* 屏幕输出应该是:
no I said thanks because I was supposed to
not because I was grateful

*/




//10.4 set类型-------------------------------------------------------------------------------------------------


// set 的键唯一性
#include <iostream>
#include <string>
#include <set>
#include <vector>
using namespace std;

int main()
{
  // define a vector with 20 elements, holding two copies of each number from 0 to 9
  vector < int > ivec;
  for(vector < int > ::size_type i = 0; i != 10; ++i)
  {
    ivec.push_back(i);
    ivec.push_back(i); // duplicate copies of each number
  }
  // iset holds unique elements from ivec
  set < int > iset(ivec.begin(), ivec.end());
  cout << ivec.size() << endl; // prints 20
  cout << iset.size() << endl; // prints 10
  return 0;
}


#include <iostream>
#include <string>
#include <set>
#include <vector>
using namespace std;
int main()
{
  // define a vector with 20 elements, holding two copies of each number from 0 to 9
  vector < int > ivec;
  for(vector < int > ::size_type i = 0; i != 10; ++i)
  {
    ivec.push_back(i);
    ivec.push_back(i); // duplicate copies of each number
  }
  
  set < string > set1; // empty set
  set1.insert("the"); // set1 now has one element
  set1.insert("and"); // set1 now has two elements
  cout << set1.size() << endl;
  
  set < int > iset2; //    empty set
  iset2.insert(ivec.begin(), ivec.end()); // iset2 has 10 elements
  cout << iset2.size() << endl;
  
  return 0;
}


// find , 键不能修改,因为是const
#include <iostream>
#include <string>
#include <set>
#include <vector>
using namespace std;
int main()
{
  set<int> iset;
  iset.insert(1);
  
  // set_it refers to the element with key == 1
  set<int>::iterator set_it = iset.find(1);
  // *set_it = 11;               // error: keys in a set are read-only
  cout << *set_it << endl;    // ok: can read the key
  
  return 0;
}


// 改写排除集单词统计
#include <iostream>
#include <string>
#include <map>
#include <set>

using namespace std;
int main()
{
  set < string > excluded;
  string remove_word;
  cout << "please input ignore words: " << endl;
  while(cin >> remove_word && "#"!=remove_word ) // 测试时,以 # 结束输入
    excluded.insert(remove_word);

  cout << "please input count words: " << endl;
  map < string, int > word_count;
  string word;
  while(cin >> word && "#"!=word) // #结束输入
    if(!excluded.count(word)) // 集合中不存在
      ++word_count[word];

  // map遍历输出
  map < string, int > ::const_iterator map_it = word_count.begin();
  while(map_it != word_count.end())
  {
    cout << map_it->first << " occurs " << map_it->second << " times" << endl;
    ++map_it; // increment iterator to denote the next element
  }
  
  return 0;
}




//10.5 multimap和multiset类型-------------------------------------------------------------------------------------------


#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
int main()
{
  multimap<string,string> authors;
  // adds first element with key Barth
  authors.insert(make_pair(string("Barth, John"), string("Sot-Weed Factor")));
  // ok: adds second element with key Barth
  authors.insert(make_pair(string("Barth, John"), string("Lost in the Funhouse")));
  cout << authors.size() << endl;
  
  return 0;
}


// erase
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
int main()
{
  multimap < string, string > authors;
  // adds first element with key Barth
  authors.insert(make_pair(string("Barth, John"), string("Sot-Weed Factor")));
  // ok: adds second element with key Barth
  authors.insert(make_pair(string("Barth, John"), string("Lost in the Funhouse")
    ));
  cout << authors.size() << endl;

  string search_item("Kazuo Ishiguro");
  // erase all elements with this key; returns number of elements removed
  multimap < string, string > ::size_type cnt = authors.erase(search_item);
  cout << cnt << endl;  
  cout << authors.size() << endl;
  
  search_item="Barth, John";
  // erase all elements with this key; returns number of elements removed
  cnt = authors.erase(search_item);
  cout << cnt << endl;  
  cout << authors.size() << endl;  
  
  return 0;
}


// 输出同一键值的多值
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
int main()
{
  multimap < string, string > authors;
  authors.insert(make_pair(string("Barth, John"), string("Sot-Weed Factor")));
  authors.insert(make_pair(string("Barth, John"), string("Lost in the Funhouse")));
  cout << authors.size() << endl;
  
  // author we'll look for
  string search_item("Barth, John");
  // how many entries are there for this author
  typedef multimap < string, string > ::size_type sz_type;
  sz_type entries = authors.count(search_item);
  cout << entries << endl;
  
  // get iterator to the first entry for this author
  multimap < string, string > ::iterator iter = authors.find(search_item);
  // loop through the number of entries there are for this author
  for(sz_type cnt = 0; cnt != entries; ++cnt, ++iter)
    cout << iter->second << endl;
  // print each title

  return 0;
}


// lower_bound , upper_bound
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
int main()
{
  multimap < string, string > authors;
  authors.insert(make_pair(string("Barth, John"), string("Sot-Weed Factor")));
  authors.insert(make_pair(string("Barth, John"), string("Lost in the Funhouse")));

  string search_item("Barth, John");
  // beg and end denote range of elements for this author
  typedef multimap < string, string > ::iterator authors_it;
  authors_it beg = authors.lower_bound(search_item), 
             end = authors.upper_bound(search_item);
  // loop through the number of entries there are for this author
  while(beg != end)
  {
    cout << beg->second << endl; // print each title
    ++beg;
  }
  
  return 0;
}


// equal_range
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
int main()
{
  multimap < string, string > authors;
  authors.insert(make_pair(string("Barth, John"), string("Sot-Weed Factor")));
  authors.insert(make_pair(string("Barth, John"), string("Lost in the Funhouse")));
  
  string search_item("Barth, John");
  typedef multimap < string, string > ::iterator authors_it;
  // pos holds iterators that denote range of elements for this key
  pair < authors_it, authors_it > pos = authors.equal_range(search_item);
  // loop through the number of entries there are for this author
  while(pos.first != pos.second)
  {
    cout << pos.first->second << endl; // print each title
    ++pos.first;
  }
  // loop through the number of entries there are for this author

  return 0;
}



//10.6 容器的综合应用:文本查询程序--------------------------------------------------------------------------------------

//

TOP

原文地址:https://www.cnblogs.com/xin-le/p/4088104.html