forked from jaege/Cpp-Primer-5th-Exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add solutions to all exercises in chapter 11.
- Loading branch information
Jaege
committed
Jan 24, 2016
1 parent
cc2d8c6
commit 39cf43f
Showing
45 changed files
with
754 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
A `map` is an associative container which contains an associative array of key-value pairs. Values are found by key. The key doesn't have to be integer. | ||
|
||
A `vector` is an sequential container which contains a normal array of values. Values are found by position. The position is integer. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
We can define `map<vector<int>::iterator, int>` because the iterator of vector supports iterator arithmetic which includes `<` operator. | ||
But we cannot define `map<list<int>::iterator, int>` because the iterator of list does not support iterator arithmetic and does not support `<` operator. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
multiset<Sales_data, bool (*)(const Sales_data &, const Sales_data &)> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include <string> | ||
#include <utility> | ||
#include <vector> | ||
#include <iostream> | ||
|
||
int main() { | ||
std::vector<std::pair<std::string, int>> vp; | ||
std::string s; | ||
int i; | ||
while (std::cin >> s >> i) | ||
vp.push_back({s, i}); | ||
//vp.push_back(std::make_pair(s, i)); | ||
//vp.push_back(std::pair<std::string, int>(s, i)); | ||
// I think the braced inititalizer is the most easy way. | ||
|
||
for (const auto &p : vp) | ||
std::cout << p.first << " : " << p.second << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
See [ex11.12](11.12.cpp). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include <string> | ||
#include <map> | ||
#include <vector> | ||
#include <utility> | ||
#include <iostream> | ||
|
||
typedef std::map<std::string, | ||
std::vector<std::pair<std::string, std::string>>> family_type; | ||
|
||
void addFamily(family_type &families, const std::string &name) { | ||
auto ret = families.insert({name, | ||
std::vector<std::pair<std::string, std::string>>()}); | ||
if (!ret.second) | ||
std::cerr << "Error: Already has family <" << name << ">" << std::endl; | ||
} | ||
|
||
void addChild(family_type &families, const std::string &family_name, | ||
const std::string &child_name, const std::string &birthday) { | ||
auto it = families.find(family_name); | ||
if (it != families.end()) | ||
it->second.push_back({child_name, birthday}); | ||
else | ||
std::cerr << "Error: No family <" << family_name << "> for child <" | ||
<< child_name << "> born on " << birthday << std::endl; | ||
} | ||
|
||
int main() { | ||
family_type families; | ||
addFamily(families, "Zhang"); | ||
addFamily(families, "Li"); | ||
addFamily(families, "Wang"); | ||
addFamily(families, "Zhang"); // Error | ||
|
||
addChild(families, "Zhang", "San", "1990-1-1"); | ||
addChild(families, "Zhang", "Bao", "1990-1-2"); | ||
addChild(families, "Zhang", "Tian", "1990-1-3"); | ||
addChild(families, "Li", "Si", "1990-1-4"); | ||
addChild(families, "Wang", "Wu", "1990-1-5"); | ||
addChild(families, "Wang", "San", "1990-1-6"); | ||
addChild(families, "Zhao", "Liu", "1990-1-7"); // Error | ||
|
||
for (const auto &family : families) | ||
for (const auto &child : family.second) | ||
std::cout << family.first << " " << child.first << " " | ||
<< child.second << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
For `map<int, vector<int>>`: | ||
|
||
- `mapped_type` is `vector<int>`. | ||
- `key_type` is `int`. | ||
- `value_type` is `pair<int, vector<int>>`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include <map> | ||
#include <iostream> | ||
|
||
int main() { | ||
std::map<int, int> mi; | ||
int a, b; | ||
while (std::cin >> a >> b) { | ||
auto it = mi.find(a); | ||
if (it != mi.end()) | ||
it->second = b; | ||
else | ||
mi.insert({a, b}); | ||
} | ||
for (auto it = mi.cbegin(); it != mi.cend(); ++it) | ||
std::cout << it->first << " : " << it->second << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Assume `multiset<string> c; vector<string> v;`, then | ||
|
||
copy(v.begin(), v.end(), inserter(c, c.end())); | ||
|
||
is OK. | ||
|
||
copy(v.begin(), v.end(), back_inserter(c)); | ||
|
||
is error. A `multiset` doesn't have `push_back` memeber function. | ||
|
||
copy(c.begin(), c.end(), inserter(v, v.end())); | ||
|
||
is OK. | ||
|
||
copy(c.begin(), c.end(), back_inserter(v)); | ||
|
||
is OK. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
The type is | ||
|
||
map<string, size_t>::const_iterator | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
The definition can be written as | ||
|
||
multiset<Sales_data, bool (*)(const Sales_data &, const Sales_data &>::iterator it = bookstore.begin(); | ||
|
||
Note that iterators for `set`s are always `const`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
A `list` may be used when we need to insert/delete at the middle frequently, such as a linked list. | ||
|
||
A `vector` may be used when we need random-access, such as a dynamic normal array. | ||
|
||
A `deque` may be used like a queue. | ||
|
||
A `map` may be used like a dictionary. | ||
|
||
A `set` may be used to check whether a value is present. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include <map> | ||
#include <set> | ||
#include <vector> | ||
#include <string> | ||
#include <iterator> | ||
#include <iostream> | ||
#include <fstream> | ||
|
||
std::string trimStr(std::string s) { | ||
constexpr char *punctuations{"\"'`:*-_;,.?!()[]{}"}; | ||
for (auto &c : s) | ||
if (c >= 'A' && c <= 'Z') c -= 'A' - 'a'; | ||
size_t bg = s.find_first_not_of(punctuations); | ||
if (bg == std::string::npos) | ||
return ""; | ||
size_t ed = s.find_last_not_of(punctuations); | ||
return s.substr(bg, ed - bg + 1); | ||
} | ||
|
||
std::map<std::string, size_t> count_words(std::vector<std::string> &words) { | ||
std::map<std::string, size_t> counts; | ||
for (const auto &w : words) { | ||
//++counts[trimStr(w)]; | ||
auto ret = counts.insert({trimStr(w), 1}); | ||
if (!ret.second) | ||
++ret.first->second; | ||
// The subscirpt way is easier to write, but hard to notice the fact that | ||
// it will add element if not existed. | ||
} | ||
return counts; | ||
} | ||
|
||
int main() { | ||
std::string filename; | ||
std::cin >> filename; | ||
std::ifstream in(filename); | ||
if (!in.is_open()) { | ||
std::cerr << "Cannot open file: " << filename << std::endl; | ||
return -1; | ||
} | ||
std::istream_iterator<std::string> i_iter(in), eof; | ||
std::vector<std::string> words(i_iter, eof); | ||
for (const auto &w : words) | ||
std::cout << w << std::endl; | ||
auto counts = count_words(words); | ||
for (const auto &w: counts) | ||
std::cout << "\"" << w.first << "\" occurs " << w.second | ||
<< (w.second > 1 ? " times." : " time.") << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
while (cin >> word) | ||
++word_count.insert({word, 0}).first->second; | ||
|
||
The code just does the same thing as `++word_count[word];`. If the `word` is in `map`, then increase the count of that word by 1, else insert that word into `map`, set the count to 0, and increase the count by 1. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The return type is `pair<map<string, vector<int>>::iterator, bool>`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <string> | ||
#include <map> | ||
#include <vector> | ||
#include <iostream> | ||
|
||
typedef std::multimap<std::string, std::vector<std::string>> family_type; | ||
|
||
void addFamily(family_type &families, const std::string &name) { | ||
families.insert({name, std::vector<std::string>()}); // always insert value | ||
//auto ret = families.insert({name, std::vector<std::string>()}); | ||
//if (!ret.second) | ||
// std::cerr << "Error: Already has family <" << name << ">" << std::endl; | ||
} | ||
|
||
void addChild(family_type &families, const std::string &family_name, | ||
const std::string &child_name) { | ||
auto it = families.find(family_name); | ||
if (it != families.end()) | ||
it->second.push_back(child_name); | ||
else | ||
std::cerr << "Error: No family <" << family_name << "> for child <" | ||
<< child_name << ">" << std::endl; | ||
} | ||
|
||
int main() { | ||
family_type families; | ||
addFamily(families, "Zhang"); | ||
addFamily(families, "Li"); | ||
addFamily(families, "Wang"); | ||
|
||
addChild(families, "Zhang", "San"); | ||
addChild(families, "Zhang", "Bao"); | ||
addChild(families, "Zhang", "Tian"); | ||
addChild(families, "Li", "Si"); | ||
addChild(families, "Wang", "Wu"); | ||
addChild(families, "Wang", "San"); | ||
addChild(families, "Zhao", "Liu"); // Error | ||
|
||
addFamily(families, "Zhang"); | ||
// OK, but the following two statement will add to the first "Zhang" key, | ||
// because we use `find()` to find the first present key. | ||
addChild(families, "Zhang", "Mei"); | ||
addChild(families, "Zhang", "Lu"); | ||
|
||
for (const auto &family : families) { | ||
std::cout << family.first << "'s family:" << std::endl; | ||
for (const auto &name : family.second) | ||
std::cout << family.first << " " << name << std::endl; | ||
std::cout << std::endl; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The code adds a new key `0` to the map `m` and value initializes its value to 0, then assigns 1 to its value. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The code will cause error. Because the subscript operator accesses element that not existed, the behaviour is undefined. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
A type which can be used as a `key_type` can be used to subscript a `map`. The subscript operator return `mapped_type`. For example: | ||
|
||
map<string, int> world_counts; | ||
string str("Hello"); | ||
int cnt = world_counts[str]; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
We can use `count` if the key is present multiple times and we want to know how many. We can use `find` if we only want to know whether the key is present. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
map<string, vector<int>> mp; | ||
map<string, vector<int>>::iterator it = mp.find("some key"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
When we pass a key that is not in container, | ||
|
||
- `upper_bound` will return `c.end()`, | ||
- `lower_bound` will return `c.end()`, | ||
- `equal_range` will return `make_pair(c.end(), c.end())`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include <map> | ||
#include <set> | ||
#include <vector> | ||
#include <string> | ||
#include <iterator> | ||
#include <iostream> | ||
#include <fstream> | ||
|
||
std::map<std::string, size_t> count_words(std::vector<std::string> &words) { | ||
std::map<std::string, size_t> counts; | ||
for (const auto &w : words) | ||
++counts[w]; | ||
return counts; | ||
} | ||
|
||
int main() { | ||
std::string filename; | ||
std::cin >> filename; | ||
std::ifstream in(filename); | ||
if (!in.is_open()) { | ||
std::cerr << "Cannot open file: " << filename << std::endl; | ||
return -1; | ||
} | ||
std::istream_iterator<std::string> i_iter(in), eof; | ||
std::vector<std::string> words(i_iter, eof); | ||
auto counts = count_words(words); | ||
for (const auto &w: counts) | ||
std::cout << w.first << " occurs " << w.second | ||
<< (w.second > 1 ? " times." : " time.") << std::endl; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
`pos` is a pair of iterators. | ||
|
||
`pos.first` is the first iterator in pair. | ||
|
||
`pos.first->second` derefences the iterator and get a pair of two strings, then returns the second string. |
Oops, something went wrong.