一、pair类型
pair包含两个数据值,与容器一样,pair也是一种模版类型。在创建pair对象时,必须提供两个类型名:pair对象所包含的两个数据成员各自对应的类型名字,这两个类型必须相同。
如:
pair anon;
pair word_count;
pair > line;
可采用typedef简化其声明:
如:typedef pair Author;
Author proust("Marcel", "Proust");
二、pair对象的操作
只需要使用普通的点操作符即可访问。first和second
如:author.first, autor.second
三、生成新的pair对象
pair next_auth;
string first, last;
cin >> first >> last;
next_auth = make_pair(first, last);
四、关联容器
1、map的构造函数
map m; 创建一个名为m的空map对象,其键和值的类型分别为k和v
map m(m2); 创建m2的副本m,m与m2必须有相同的键类型和值类型。
map m(b, e); 创建map类型的对象m,存储迭代器b和e标记范围内所有元素的副本。元素的类型
必须能转换为 pair
2、键类型的约束条件
键类型必须定义 < 操作符,而且该操作符必须能“正确地工作”
3、map定义的类型
map::key_type; 在map容器中,用做索引的键的类型
map::mapped_type; 在map容器中,键所关联的值的类型
map::value_type; 一个pair类型,它的first元素具有const map::key_type类型,而second元素则为map::mapped_type类型。它的值成员可以修改,键成员不能修改。
map迭代器进行解引用将产生pair类型的对象。
对迭代器进行解引用操作时,将获得一个引用,指向容器中一个value_type类型的值。
//在一个word_count容器中获取一个迭代器
map::iterator map_it = word_count.begin();
cout << "key = " << map_it->first << " value = " << map_it->second << endl;
map_it->first = "new key" ;// 错误,key is const
++map_it->second; //正确,我们能够改变其值通过迭代器
对迭代器进行解引用将获得一个pair对象,它的first成员存放键,为const,而second成员存放值。
4、给map添加元素
下标行为的编程意义:
对于map容器,如果下标所表示的键在容器中不存在,则添加新元素。
map迭代器返回value_type类型的值,为pair对象,下标操作返回一个mapped_type类型的值。
5、map::insert 的使用
map容器提供的insert操作
m.insert(e); e是一个用在m上的value_type类型的值,如果键e.first不在m中,则插入一个值为e.second的新元素。如果该键在m中已存在,则保持m不变。该函数返回一个pair类型对象,包含指向键为e.first的元素的map迭代器,以及一个bool类型的对象,表示是否插入了该元素。
m.insert(beg, end) beg 和 end 是标记元素范围的迭代器,其中的元素必须为
m.value_type 类型的键-值对。对于该范围内的所有元素,如果它的键在 m 中不存在,则将该键及其关联的值插入到 m。返回 void 类型
m.insert(iter, e) e 是一个用在 m 上的 value_type 类型的值。如果键(e.first)不在 m 中,则创建新元素,并以迭代器 iter 为起点搜索新元素存储的位置。返回一个迭代器,指向 m 中具
有给定键的元素
6、查找并读取map中的元素
用下标方法可以获取一个元素,但是当元素不存在时,就会插入一个元素,这点需要明白。所以一般
如果不是有目的,用下面的方法更合理。
m.count(k) //返回m中k出现的次数
m.find(k) //如果m容器中存在按K索引的元素,则返回指向该元素的迭代。不存在,则返回超出末端迭代器。
读取元素而不插入该元素
int occurs = 0;
map::iterator it = word_count.find("foobar");
if(it != word_count.end())
occurs = it->second;
7、从map对象中删除元素
m.erase(k); 删除m中键为k的元素,返回size_type类型的值,表示删除的元素的个数。
m.erase(p); 从m中删除迭代器p所指向的元素,p必须指向m中确实存在的元素,且不能等于m.end(),返回void
m.erase(b ,e); 从m中删除一段范围内的元素,该范围由迭代器b和e标记。
8、map对象的迭代遍历
map::const_itertor map_it = word_count.begin();
while (map_it != word_count.end())
{
cout << map_it->first << " occors "
<< map_it->second << " times" << endl;
++map_it;
}
实例,单词转换对,a文件包含单词转换的对,将b文件按a中的对应关系进行转换。
文本查询程序代码:
1、按行读取某个文件中的内容到vector,按顺序存储。
2、将单词存放到map中,键为单词,值为单词所在的行的集合(set)。
3、查询某个单词时,打印该单词所在的行,以及所在行的内容。
querrymain.cpp
- #include "text_query.hpp"
- #include <string>
- #include <vector>
- #include <map>
- #include <set>
- #include <iostream>
- #include <fstream>
- #include <cctype>
- #include <cstring>
- #include <cstdlib>
- using std::set;
- using std::string;
- using std::map;
- using std::vector;
- using std::cerr;
- using std::cout;
- using std::cin;
- using std::ifstream;
- using std::endl;
- string make_plural(size_t, const string&, const string&);
- ifstream& open_file(ifstream&, const string&);
- string make_plural(size_t ctr, const string &word,
- const string &ending)
- {
- return (ctr != 1) ? word + ending : word;
- }
- ifstream& open_file(ifstream & in,const string & file)
- {
- in.close();
- in.clear();
- in.open(file.c_str());
- return in;
- }
-
- void print_results(const set<TextQuery::line_no>& locs,
- const string& sought, const TextQuery &file)
- {
- // if the word was found, then print count and all occurrences
- typedef set<TextQuery::line_no> line_nums;
- line_nums::size_type size = locs.size();
- cout << "\n" << sought << " occurs "
- << size << " "
- << make_plural(size, "time", "s") << endl;
- // print each line in which the word appeared
- line_nums::const_iterator it = locs.begin();
- for ( ; it != locs.end(); ++it) {
- cout << "\t(line "
- // don't confound user with text lines starting at 0
- << (*it) + 1 << ") "
- << file.text_line(*it) << endl;
- }
- }
- int main(int argc, char **argv)
- {
- ifstream infile;
- if (argc < 2 || !open_file(infile, argv[1]))
- {
- cerr << "No input file!" << endl;
- return EXIT_FAILURE;
- }
- TextQuery tq;
- tq.read_file(infile);
- tq.display_map();
- // iterate with the user: prompt for a word to find and print results
- // loop indefinitely; the loop exit is inside the while
- while (true)
- {
- cout << "enter word to look for, or q to quit: ";
- string s;
- cin >> s;
- // stop if hit eof on input or a 'q' is entered
- if (!cin || s == "q") break;
- // get the set of line numbers on which this word appears
- set<TextQuery::line_no> locs = tq.run_query(s);
- // print count and all occurrences, if any
- print_results(locs, s, tq);
- }
- return 0;
- }
Text_query.hpp
- #ifndef TEXTQUERY_HPP
- #define TEXTQUERY_HPP
- #include <string>
- #include <vector>
- #include <map>
- #include <set>
- #include <iostream>
- #include <fstream>
- #include <cstring>
- using std::ifstream;
- class TextQuery{
- public:
- typedef std::string::size_type str_size;
- typedef std::vector<std::string>::size_type line_no;
- /* interface:
- * read_file builds internal data structures for the given file
- * run_query finds the given word and returns set of lines on which it appears
- * text_line returns a requested line from the input file
- */
- void read_file(ifstream &is)
- { store_file(is); build_map();}
- std::set<line_no> run_query(const std::string&) const; //形参表后跟上const 表示该函数为常量成员函数,const成员函数不能修改调用该函数的对象,
- std::string text_line(line_no) const;
- str_size size() const {return lines_of_text.size();}
- void display_map();
- private:
- void store_file(ifstream&);
- void build_map();
- //
- std::vector<std::string> lines_of_text;
- //set
- std::map< std::string, std::set<line_no> > word_map;
- static std::string whitespace_chars;
- static std::string cleanup_str(const std::string&);
- };
- #endif
TextQuery.cpp
阅读(1557) | 评论(0) | 转发(0) |