《Essential C++》 第三章 泛型编程风格-课后习题收获

习题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;//如果返回不是0,说明已经存在,则跳过
		word_count[content]++;
		//创建一个key,并且+1,防止默认值为0,误以为不存在

收获:如果知道是一个容器,用容器共通操作可以降低代码量。

习题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());
如果把第三个参数换成函数会出现这样的提示:

//class greater_LessThan
//{
//public:
	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)最后一节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值