第十章 关联容器
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\n"; else cout << "oops: " << removal_word << " not found!\n"; 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 容器的综合应用:文本查询程序-------------------------------------------------------------------------------------- // 略