c++ primer第五版----学*笔记(十一)Ⅱ

发布时间:2021-11-30 22:44:00

部分*题解答:


11.1:


vector这种顺序容器,元素在其中按顺序存储,每个元素都有唯一对应的位置编号,所有操作都是按编号进行的。例如,获取元素,插入删除元素,遍历元素。底层的数据结构是数组、链表,简单但能保证上述操作的高效。对于依赖值的元素访问,例如查找给定值,在这种数据结构上的实现是要通过遍历完成的,效率不佳。
而map这种关联容器,就是为了高效实现“按值访问元素”这类操作而设计的。为了达到这一目的,容器中的元素是按关键字值存储的,关键字值与元素数据建立起对应关系。底层数据结构是红黑树、哈希表等,可高效实现按关键字值查找、添加、删除元素等操作。


11.2:


若元素很小(例如int),大致数量预先可知,在程序运行过程中不会剧烈变化,大部分情况下只在末尾添加或删除需要频繁访问任意位置的元素,则vector可带来最高的效率。若需要频繁在头部和尾部添加或删除元素,则deque是最好的选择。
如果元素较大(如大的类对象),数量预先不知道,或是程序运行过程中频繁变化,对元素的访问更多是顺序访问全部或很多元素,则list很适合。
map适合对一些对象按它们的某个特征进行访问的情形。set就是集合类型,当需要保存特定的值集合(通常是满足/不满足某种要求的值的集合),用set最为方便。


11.3:


#include
#include
#include
#include
#include
using namespace std;

int main(int argc, char**argv)
{
map word_count;
string word;
while (cin >> word)
{
++word_count[word];
}
for (auto &w : word_count)
{
cout << w.first << "occurs" << w.second << ((w.second > 1) ? "times" : "time") << endl;
}
system("pause");
return 0;
}

11.4:


#include
#include
#include
#include
#include
using namespace std;

int main(int argc, char**argv)
{
map word_count;
string word;
string punct = ",.";
while (cin >> word)
{
auto pos = word.find_first_of(punct);
if (pos != string::npos) //查找单词里面如果出现,或.则将它们删除
{
word.erase(pos);
}
for (auto &c : word) //将大写字母改为小写
{
if (isupper(c))
{
c = tolower(c);
}
}
++word_count[word];
}
for (auto &w : word_count)
{
cout << w.first << " occurs " << w.second << ((w.second > 1) ? "times" : "time") << endl;
}
system("pause");
return 0;
}

11.5:


map:当需要查找给定值对应的数据时,使用map


set:当只需要判定给定值是否存在时,使用set


11.6:


set与list都保存元素值,如果只需要顺序访问或位置访问这些元素,使用list;如果需要快速判断是否有值等于给定值,使用set


11.7:


#include
#include
#include
#include
#include
using namespace std;

//注意以下两个函数的参数map需要使用引用,因为需要修改map的数据
void add_family(map < string, vector> &family, const string &s)
{
if (family.find(s) == family.end())
{
family[s] = vector (); //创建一个匿名变量,也可不创建,直接使用family[s];即可
}
}
void add_child(map> &family, const string &s, const string &child)
{
family[s].push_back(child);
}

int main(int argc, char**argv)
{
map> family;
add_family(family, "zhang");
add_family(family, "li");
add_child(family, "zhang", "shan");
add_child(family, "zhang", "ying");
add_child(family, "li", "bai");
for (auto f : family)
{
cout << f.first << ":";
for (auto c : f.second)
{
cout << c << " ";
}
cout << endl;
}
system("pause");
return 0;
}

11.8:


#include
#include
#include
#include
#include
using namespace std;

void erase_the_same( string &s)
{
string punct{ ",." };
auto it = s.begin();
auto pos = s.find_first_of(punct);
if (pos != string::npos) //查找单词里面如果出现,或.则将它们删除
{
s.erase(pos);
}
if (isupper(*it))
{
*it = tolower(*it);
}
}

int main(int argc, char**argv)
{
vector vec;
string word;
while (cin >> word)
{
erase_the_same(word);
if (find(vec.begin(), vec.end(), word) == vec.end())
{
vec.push_back(word);
}
}
for (auto &c : vec)
{
cout << c << " ";
}
system("pause");
return 0;
}

11.9:


#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

void erase_the_same( string &s)
{
string punct{ ",." };
auto it = s.begin();
auto pos = s.find_first_of(punct);
if (pos != string::npos) //查找单词里面如果出现,或.则将它们删除
{
s.erase(pos);
}
if (isupper(*it))
{
*it = tolower(*it);
}
}

int main(int argc, char**argv)
{
map> word_line;
string line;
string word;
size_t _line = 0;
ifstream in("11.txt");
while (getline(in, line))
{
++_line;
istringstream in(line); //处理一行中的每个单词
while (in >> word)
{
erase_the_same(word);
word_line[word].push_back(_line);
}
}
for (auto &f : word_line)
{
cout << f.first << " is in: ";
for (auto &w : f.second)
{
cout << w << " ";
}
cout << endl;
}
system("pause");
return 0;
}

11.10:


vector容器的迭代器支持比较操作,而list不是连续存储的,不支持比较操作,所以前者可定义,后者不可以


11.11:


typedef bool(*pf) (const Sales_data&,const Sales_data&);
multiset bookstore(compareIsbn);

11.12:


#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

int main(int argc, char**argv)
{
vector> vec;
string word;
int num;
while (cin >> word && cin >> num) //输入一个字符串之后接着输入数字
{
vec.push_back({ word,num });
}
for (auto &c : vec)
{
cout << c.first << " " << c.second << endl;
}
system("pause");
return 0;
}

11.13:


vec.push_back({ word,num });
vec.push_back(pair(word,num));
vec.push_back(make_pair(word,num));

11.14:


#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;


//注意以下两个函数的参数map需要使用引用,因为需要修改map的数据
void add_family(map < string, vector>> &family, const string &s)
{
if (family.find(s) == family.end())
{
family[s];
}
}
void add_child(map>> &family, const string &s, const string &child,const string &birthday)
{
family[s].push_back({ child,birthday });
}

int main(int argc, char**argv)
{
map>> family;
add_family(family, "zhang");
add_family(family, "li");
add_child(family, "zhang", "shan","1998-11-24");
add_child(family, "zhang", "ying","1997-10-25");
add_child(family, "li", "bai","1996-09-26");
for (auto f : family)
{
cout << f.first << ":";
for (auto c : f.second)
{
cout << c.first << " " << c.second << " ";
}
cout << endl;
}
system("pause");
return 0;
}

11.16:


map mp;
auto f = mp.begin();
f->second = 0;

11.17:


set的迭代器是const的,因此只允许访问set中的元素,而不能改变set。与map一样,set的关键字也是const,因此不能通过迭代器来改变set重元素的值。因此,前两个调用试图将vector中的元素复制到set中,是非法的。而后两个调用将set中的元素复制到vector中,是合法的。


11.18:


pair::iterator

11.19:


typedef bool(*pf)(const Sales_data &, const Sales_data &);
mutiset bookstore(compareIsbn;
pair ::iterator it = bookstore.begin();

11.20:


#include
#include
#include
#include
#include
using namespace std;

int main(int argc, char**argv)
{
map word_count;
string word;
while (cin >> word)
{
auto ret = word_count.insert({ word, 1 }); //返回一个pair
if (!ret.second) //若ret.second为false,则!ret.second为true,执行下面的操作
++ret.first->second; //递增计数器
}
for (auto &w : word_count)
{
cout << w.first << "occurs" << w.second << ((w.second > 1) ? "times" : "time") << endl;
}
system("pause");
return 0;
}

11.22:


pair> //参数类型
pair>::iterator, bool> //返回类型

11.23:


#include
#include
#include
#include
#include
using namespace std;


void add_child(multimap> &family, const string &s,const vector &child)
{
family.insert({ s,child });
}

int main(int argc, char**argv)
{
multimap> family;
add_child(family, "zhang", { "shan","yang" });
add_child(family, "li", { "bai","qiang" });
for (auto f : family)
{
cout << f.first << ":";
for (auto c : f.second)
{
cout << c << " ";
}
cout << endl;
}
system("pause");
return 0;
}

11.24:


若m中已有关键字0,下标操作提取出其值,赋值语句将其值置为1.


否则下标操作会创建一个pair(0,0),即关键字为0,值为0,将其插入到m中,然后提取其值,赋值语句将其置为1.


11.25:


若v中已有不少于一个元素,则下标操作提取出此位置的元素,赋值操作将其置为1;如v为空,则下标提取出的是一个非法左值,向其赋值可能会导致系统崩溃等严重后果。


11.27:


希望知道容器中有多少元素与关键字相同时使用count;希望知道关键字是否在容器中使用find


11.28:


map>::iterator iter;

11.30:


equal_range返回一个pair,其first成员与lower_bound的返回结果相同,即指向容器中第一个具有给定关键值的元素。因此,对其解引用会得到一个value_type对象,即一个pair,其first为元素的关键字,即给定关键字,second为关键字关联的值。本题中,输出给定作者的第一部著作的题目。


11.31:


#include
#include
#include
#include
#include
#include
using namespace std;

void erase_book(multimap &book, const string &author)
{
auto ret = book.equal_range(author); //返回一个pair,范围为容器满足条件的所有元素
if (ret.first == ret.second)
{
cout << "no this author" << endl;
}
else
{
book.erase(ret.first, ret.second);
}
}

void output_book(multimap book)
{
for (auto &f : book)
{
cout << f.first << ":" << f.second << endl;
}
}
int main(int argc, char**argv)
{
multimap books;
books.insert(make_pair( "江南", "天之炽"));
books.insert(make_pair("江南", "龙族"));
books.insert(make_pair("江南", "此间的少年"));
books.insert({ "东野圭吾","嫌疑人x的献身" });
output_book(books);
erase_book(books, "江南");
cout << endl;
output_book(books);
system("pause");
return 0;
}

11.32:


#include
#include
#include
#include
#include
#include
#include
using namespace std;

void erase_book(multimap &book, const string &author)
{
auto ret = book.equal_range(author); //返回一个pair,范围为容器满足条件的所有元素
if (ret.first == ret.second)
{
cout << "no this author" << endl;
}
else
{
book.erase(ret.first, ret.second);
}
}

void output_book(multimap book)
{
map> order_book; //用来排序的map
for (auto &f : book)
{
order_book[f.first].insert(f.second);
}

for (auto &f : order_book)
{
cout << f.first << ":";
for (auto &w : f.second)
{
cout << w << endl;
}
}
}
int main(int argc, char**argv)
{
multimap books;
books.insert(make_pair( "江南", "天之炽"));
books.insert(make_pair("江南", "龙族"));
books.insert(make_pair("江南", "此间的少年"));
books.insert({ "东野圭吾","嫌疑人x的献身" });
output_book(books);
erase_book(books, "江南");
cout << endl;
output_book(books);
system("pause");
return 0;
}

11.33:


#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

map
buildmap(ifstream &map_file)
{
map trans_map; //保存转换规则
string key; //要转换的单词
string value; //替换后的内容
//读取第一个单词存入key中,行中剩余内容存入value
while (map_file >> key && getline(map_file, value))
{
if (value.size() > 1)
{
trans_map[key] = value.substr(1); //value为关键字之后的所有字符,包括与关键字之间的空格,所以令参数为1消去空格
}
else
throw runtime_error("no rule for " + key);
}
return trans_map;
}
const string &
transform(const string &s, const map &m)
{
auto map_it = m.find(s);
//如果单词在转换规则之中
if (map_it != m.cend())
{
return map_it->second; //使用替换短语
}
else
return s; //如果单词不在转换规则中,则返回原单词
}
void word_transform(ifstream &map_file, ifstream &input)
{
auto trans_map = buildmap(map_file); //保存转换规则
string text; //保存输入的每一行
while (getline(input, text)) //读取每一行输入
{
istringstream stream(text); //读取一行中的每个单词
string word;
bool firstword = true; //控制是否打印空格
while (stream >> word)
{
if (firstword) //如果读取的单词不为空,则之后打印一个空格
firstword = false;
else
cout << " ";
cout << transform(word, trans_map); //将需要转换的单词转换
}
cout << endl;
}
}
int main(int argc, char**argv)
{
ifstream map_file("11.txt");
ifstream input("11.1.txt");
word_transform(map_file, input);
system("pause");
return 0;
}

11.34:


下标运算符的行为与find类似,但当关键字不存在时,它会构造一个pair,将其插入到容器中


11.35:


当map中没有给定关键字时。insert和下标操作+赋值操作效果类似,都是将关键字和值的pair添加到map中。当map中已有给定关键字,下标操作会获得具有该关键字的元素的值,并将新读入的值赋予它,但insert操作遇到关键字已存在的情况,则不会改变容器内容,而使返回一个值指出插入失败。当规则文件中存在多条规则转换相同单词时,下标+赋值的版本最终会用最后一条规则进行文本转换,而insert版本则会用第一条规则转换。


11.37:


无序版本通常性能更好,使用也更为简单。有序版本的优势是维护了关键字的顺序。当元素的关键字类型没有明显的序关系,或是维护元素的序代价非常高时,无序容器非常有用。但当应用要求必须维护元素的序时,有序版本就是唯一的选择。

相关文档

  • 低血压高血糖症状
  • 徐玉玉 骗徐玉玉的人抓到了吗? 被骗大学生徐玉玉家庭背景爸爸做什么的
  • 七年级历史上册单元测试卷带答案
  • 客厅摆放什么植物好招财
  • 手机安全清理
  • 直冷和风冷
  • 重点学校教导主任竞聘演讲稿范文
  • GNN手写字体识别java,Java中反射机制(Reflection)研究及源码演示
  • 魅族系统怎么换原来
  • 闯红灯作文300字
  • 男性增加雄激素吃什么好男性缺乏雄激素怎么调理
  • 把木兰诗改写成故事
  • 如何去黑头和收缩毛孔
  • 调和油和大豆油哪个好 大豆油怎么吃
  • 销售员的工作计划
  • 尿片固定带品牌十大排行榜
  • 超短搞笑微信签名
  • 热门新学期学习计划集锦9篇
  • 山西专升本考试报名时间
  • 小米平板桌面怎么添加小工具
  • 祭祖作文
  • numpy中axis的通俗理解
  • VC++常见问题的整理
  • 前列腺炎的成因与不孕不育
  • 县委副书记在薯业协会成立仪式上的讲话
  • 生物科学小知识分类大全
  • DeepStream进阶插件之路
  • 能消除黑眼圈的最快方法
  • 北宋文学女性形象
  • 她是第一个遭到宗教迫害的科学家
  • 猜你喜欢

  • 舒城县爱久久婚庆有限公司企业信用报告-天眼查
  • 为什么高山上的花朵特别艳丽?
  • 小学生感谢学校老师的话
  • 第七章决策分析(3)
  • 育儿知识-学会这些,财商教育轻松做!
  • 小学议论文作文:读《选我选我!花路米》有感2
  • 应届毕业生个人简历
  • 达州市财务咨询公司研究报告2018版
  • 【强烈推荐】苏教版六年级课外阅读测试题《漂亮老师和坏小子》(包含答案)
  • 深圳市一禾兴电子有限公司(企业信用报告)- 天眼查
  • 华为x4手机有什么特殊功能
  • 2005年山东大学固态化学考博真题考博试题博士研究生入学考试试题
  • 冬天下雪作文
  • b系列模块化风管送风式空调机组设计选型手册
  • 太阳能专业英语翻译剖析
  • [精品]2019学年高二地理上学期入学考试试题(含解析)
  • 三大开源生信基础教程和视频课程
  • 考研数学_高等数学(09冲刺)讲义
  • 2017年幼儿园毕业典礼主持词开场白
  • 【2019-2020】201X四年级语文期末知识点古诗复习-范文word版 (2页)
  • iphone怎么一键取消文件夹
  • 最新-市人大机关扶贫工作计划 精品
  • 这家火锅店分店很多,在寒冬里那份炙热让人永远难忘:香猪坊
  • 2018-2019学年重庆市大学城一中九年级(上)第一次月考化学试卷
  • LC椭圆函数带通滤波器的设计及仿真
  • 河南省发展和改革委员会关于切实做好2008年立法工作的通知
  • 同学聚会怀旧电子相册PPT模板
  • XX年简单租房合同模板_1
  • 幸福的滋味优秀作文500字
  • 二年级下语文字词句期末复习
  • 2019年温州市中考物理模拟试题与答案
  • 关于危旧房改造工作总结范文
  • GUILLEMARD (SINGAPORE) PTE.LTD.企业信息报告-天眼查
  • 顶岗实习工作自我总结范文
  • 超级QQ和QQ会员合并怎么回事
  • 北师大版小学二年级上册数学《动物聚会》教案
  • 让你笑到泪崩的一句话段子
  • 我的启蒙老师_三年级作文_3
  • 精品-高考政治一轮复*第十四单元思想方法与创新意识第37课唯物辩证法的实质与核心课件新人教版必修4
  • LMQ.J立式压力蒸汽灭菌器和立式压力蒸汽灭菌器价格
  • 成都市科学技术局关于2007年国家火炬计划重点高新技术企业申报和20
  • 适龄妇女计划生育生殖健康检查工作方案
  • 电脑版