习题3–1:
1.关于map的查询操作
实现的功能:确保从file中读出来的map没有set里有的值,比如set={a,the},文件中"the boy is a student"。去掉后变成map={{boy,1},{is,1},{student,1}}。 我的方法:
if (find(exclude_set.begin(), exclude_set.end(),
content) != exclude_set.end())
word_count[content]++;
content是从file读出的单词,每读出一个content就和set中元素一一比对,如果不是set里的单词,就放进map。
参考答案:
if (exclude_set.count(content))
continue;
word_count[content]++;
收获:如果知道是一个容器,用容器共通操作可以降低代码量。
习题3–2、写一个Function Object:
实现:根据字符串长度来进行排序。 首先,sort(首地址,尾地址,比对方法),比对方法是sort在处理时采用的方法,该Function Object必须返回bool值
class size_LessThan
{public:
bool operator()(const string& s1, const string& s2)
{return s1.size() < s2.size();}
};
class greater_LessThan
{public:
bool operator()(const string& s1, const string& s2)
{return s1.size() > s2.size();}
};
调用方法sort(m_words.begin(), m_words.end(), size_LessThan()); 如果把第三个参数换成函数会出现这样的提示:
bool greater_LessThan(const string& s1, const string& s2)
{
return s1.size() > s2.size();
}
但写成函数显然不实际,但是排序是针对所有元素的,指定某两个string就显得不实际了。 所以对于Function Object,我的理解是:给函数实现特定功能的工具,函数会调用这个Function Object,至于sort如何使用,对我们来说是不知道的,但知道他是为了实现排序功能。
习题3.3:
对于具有如下格式的txt.文件
Zhang San Liang Sanfeng Xueliang
Liu Xiang Yifei
Liang Jiahui Jingru
每一行的第一个单词为"姓",后面的单词都是“名”。读出全部内容,用map进行记录。
1、定义方法
map<string,vector<string>> name;
2、读文件的方法
2.1、按行读取
while (getline(namefile, textline))
{}
按一定条件读取文件,第三参数默认为换行。 这样第一次循环为:Zhang San Liang Sanfeng Xueliang 第一次循环为:Liu Xiang Yifei …
2.2、读取单词的方法
?? 用两个指针,一个在右pos,一个在左pre_pos。pos找到这一行下一个空格的位置,比如“Zhang San Liang Sanfeng Xueliang” ,
第一次循环pre_pos=0,pos=5。则可以知道第一个单词长度为5,读出这五个字符。读出来后pos=5+1,pre_pos=pos。下一个循环。 第二次循环pre_pos=6,pos=9。则可以知道第二个单词长度为9-6=3,读出这3个字符。。。
必要的函数:1.textline.find_first_of(' ', possition) ,找到从possition为起点的第一个空格的地址,由于起点可能是空格,所以上面的循环中,读出字符后,要pos++,不然一直停在原地。 2.textline.substr(prev_possition, len_ofstr) 把textline中从prev_pos开始,长度为 len_ofstr的string提出来
2.3、含有vector的map的数据查询
需要至少两个指针才能更加清晰:
第一个指针:map<string, vector>::const_iterator it = families.begin(); 即指向这个map首地址的指针。 第二个指针:vector ::const_iterator vit = it->second.begin(); 即指向map首地址的value的指针。
这样遍历"姓"可以通过以下代码
while(it!=families.end())
{
cout<<*(it->first);
it++;
}
遍历某一个"姓"下的名
while(vit!= (it->second.end())
{
cout<<*vit;
vit++;
}
贴个图吧
1.vit是不知道总共有多少个名字的,因此需要vit!= (it->second.end() 确保其在有效范围内。 2.不管是姓还是名的尾地址都可以通过it知道。it->first即当前it位置的姓,it->second.begin()即当前it位置的名首地址。为了避免过长的指向关系,因此用vit=it->second.begin()
4.4 太简单了,直接看笔记(2)最后一节
|