C++Prime 第十一章

C++Prime 第十一章

练习11.1

map以关键字来存储和访问,vector以元素在容器中的位置来存储和访问.

练习11.2

list: 插入&删除,如链表中间插入一个数据

vector: 随机访问,

deque: 头尾插删,

map: 关键字存储,如字典

set:关键字的集合.如判断一个元素是否在集合中出现过

练习11.3

	map<string, size_t> word_count;
	string word;
	while (cin >> word)
		++word_count[word];
	for (const auto& w : word_count)
		cout << w.first << "occurs  " << (w.second << (w.second > 1) ? "times" : "time")<< endl;

练习11.4

int main()
{
	map<string, size_t> word_count;
	string word;
	while (cin >> word)
	{
		if (isupper(word[0]))//大小写
			word[0] = tolower(word[0]);
		if (ispunct(word[word.size() - 1]))//标点
			word.erase(word.size() - 1);
		++word_count[word];
	}
	for (const auto& w : word_count)
		cout << w.first << " occurs  " << w.second << ((w.second > 1) ? " times" : " time")<< endl;

	return 0;
}

练习11.5

最大的区别是map的关键字关联到一个值,而set的值就是关键字本身.需要集合类型时选择set,需要存储多余信息时选择map

练习11.6

set的值不重复,且有序.

练习11.7

int main()
{
	map<string, vector<string> > m;
	string tmp;
	cout << "Please enter first name (q to quit):\n";
	while (cin >> tmp && tmp != "q")
	{
		cout << "Please enter child name (q to quit):\n";
		while (cin >> tmp && tmp != "q")
			m[tmp].push_back(tmp);
		cout << "Please enter first name (q to quit):\n";
	}
	return 0;
}

练习11.8

自动排序,单词不重复则不会丢失单词.查找快速.

练习11.9

int main()
{
	map<string, list<int> > m;
	istream_iterator<string> sin(cin), send;
	while (sin != send)
	{
		istream_iterator<int> in(cin), end;
		copy(in, end, inserter(m[*sin], m[*sin].begin()));
	}

	return 0;
}

练习11.10

vector迭代器可以直接比较大小,但是要求所有的map中的迭代器指向同一个vector,否则还是报错.

list迭代器不可以用作关键字,因为不可以直接比较大小.

练习11.11

方法一:重载<运算符.

方法二:参考P.223,定义函数指针.

	//使用decltype(fun) * 来指定函数指针

	//使用using声明
	using F = bool(*)(const Test& , const Test& );
	set<Test, F> m(compareIsbn);
	
	//最普通的方法
	set<Test, bool(*)(const Test&, const Test&)> m1(compareIsbn);

	//使用typedef
	typedef bool(*pf)(const Test&, const Test&) ;
	set<Test,pf> m2(compareIsbn);

	//typedef + decltype
	typedef decltype(compareIsbn)* pf2;
	set<Test, pf2> m2(compareIsbn);

练习11.12

int main()
{
	vector<pair<string, int> >a;
	string tmp;
	while (cin>>tmp)
	{
		int num;
		cin >> num;
		a.push_back({ tmp,num });
	}
	for_each(a.begin(), a.end(), [](const pair<string, int>& p) {cout << p.first << " " << p.second << endl; });
	return 0;
}

练习11.13

make_pair,

{},

pair<string,int>("sf",2),

emplace_back("string",12)

练习11.14

OK

练习11.15

mapped_type 是映射的值类型,即vector<int>

key_type 是关键字类型,即int

value_type 是pair<int,vector<int>>

练习 11.16

int main()
{
	map<string, int> m{ {"hello",1},{"world",2} };
	auto p = m.begin();
	while (p != m.end())
	{
		if (p->first == "hello")
			p->second = 100;
		p++;
	}
	for (const auto& x : m)
		cout << x.first << " " << x.second << endl;
}

练习11.17

第二个调用不合法,关联容器的push_back操作是违法的,无意义.

练习11.18

pair<string,size_t>::iterator

练习11.19

	multiset<Sales_data, decltype(compareIsbn)* >::const_iterator = bookstore.begin();

练习11.20


int main()
{
	map<string, size_t> word_count;
	string word;
	while (cin >> word)
	{
		auto ret = word_count.insert({ word,1 });
		if (!ret.second)
			++ret.first->second;
	}
	for (const auto& w : word_count)
		cout << w.first << "occurs  " << (w.second << (w.second > 1) ? "times" : "time") << endl;


}

练习11.21

单词计数

练习11.22

pair<string,vector<int> >;//插入

pair<map<string,vector<int> >::iterator,bool );//返回

练习11.24

将m中关键字为0的元素(如果存在,这里肯定不存在,空map)它的映射的值变为1,如果不存在,则创建一个pair<0,1>.

练习11.25

v的首元素变为1,v为空vector,所以直接报错.

练习11.26

关键字的类型key_type可以用做下标.

返回的类型是映射的值的类型mapped_type.

map<string,int > m;

string可以用来下标操作,返回int

练习11.27

需要统计有多少个元素在容器中时,可以选择count

练习11.28

	map<string, vector<int> >m;
	map<string, vector<int> >::iterator p = m.find("dsf");

练习11.29

lower_bound 和 upper_bound 都指向关键字可以插入的位置,equal_range返回一个pair,两个成员函数同指向关键字可以插入的位置.

练习11.30

pos是一个pair对象,其first成员是个迭代器,迭代器的second指向题目

练习11.31

int main()
{
	
	multimap<string, string> m;
	m.insert({ "zhang","math" });
	m.insert({ "zhang","english" });
	m.insert({ "liu","math" });
	m.insert({ "zhang","chinese" });
	m.insert({ "zhao","ecology" });
	auto p = m.find("zhang");
	auto n = m.count("zhang");
	while (n)
	{
		if (p->second == "english")
		{
			m.erase(p);
			break;
		}
		++p;
		--n;
	}
}

练习11.32

int main()
{
	multimap<string, string> m;
	m.insert({ "zhang","math" });
	m.insert({ "zhang","english" });
	m.insert({ "liu","math" });
	m.insert({ "zhang","chinese" });
	m.insert({ "zhao","ecology" });
	auto p = m.find("zhang");
	auto n = m.count("zhang");
	while (n)
	{
		if (p->second == "english")
		{
			m.erase(p);
			break;
		}
		++p;
		--n;
	}
	for (auto it = m.begin(); it != m.end(); ++it)
	{
		cout << it->first << "  "<<it->second<<endl;
	}
	return 0;
}

练习11.33

map<string, string> buildMap(ifstream& map_file)
{
	map<string, string> trans_map;
	string key;
	string value;

	while (map_file >> key && getline(map_file, value))
	{
		if (value.size() > 1)
			trans_map[key] = value.substr(1);
		else
			throw runtime_error("no rule for " + key);
	}
	return trans_map;
}
const string& transform(const string& s, const map<string, string>& 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;
	}
}

练习11.34

会报错.因为map是const的,而下标运算企图改变map

练习11.35

下标运算每次都会更新值,insert不会更新

练习11.36

抛出异常.

练习11.37

无序版本避免了让大量数据变得有序而带来的消耗

有序版本让关键字有序

练习11.38

加油

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值