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 soultions to second half of exercises in chapter 9.
- Loading branch information
Jaege
committed
Jan 21, 2016
1 parent
8e35365
commit 1576acc
Showing
27 changed files
with
602 additions
and
5 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include <forward_list> | ||
#include <iostream> | ||
|
||
int main() { | ||
std::forward_list<int> fli{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; | ||
auto pre = fli.before_begin(); | ||
auto cur = fli.begin(); | ||
while (cur != fli.end()) { | ||
if (*cur % 2) { | ||
cur = fli.erase_after(pre); | ||
} else { | ||
pre = cur; | ||
++cur; | ||
} | ||
} | ||
|
||
for (const auto &i : fli) | ||
std::cout << i << " "; | ||
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,41 @@ | ||
#include <forward_list> | ||
#include <string> | ||
#include <iostream> | ||
|
||
void insertAfterStr(std::forward_list<std::string> &fls, | ||
const std::string &s1, | ||
const std::string &s2) { | ||
auto pre = fls.before_begin(); | ||
auto cur = fls.begin(); | ||
while (cur != fls.end()) { | ||
if (*cur == s1) { | ||
fls.insert_after(cur, s2); | ||
return; | ||
} else { | ||
pre = cur++; | ||
} | ||
} | ||
fls.insert_after(pre, s2); | ||
} | ||
|
||
int main() { | ||
std::forward_list<std::string> fls{"s1", "s2", "s3"}; | ||
|
||
for (const auto &s : fls) | ||
std::cout << s << " "; | ||
std::cout << std::endl; | ||
|
||
insertAfterStr(fls, "s2", "s4"); | ||
|
||
for (const auto &s : fls) | ||
std::cout << s << " "; | ||
std::cout << std::endl; | ||
|
||
insertAfterStr(fls, "s5", "s6"); | ||
|
||
for (const auto &s : fls) | ||
std::cout << s << " "; | ||
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,3 @@ | ||
`vec.resize(100)` will append 75 value initialized elements at the end of `vec`. | ||
|
||
`vec.resize(10)` will remove 90 elements from the end of `vec`. |
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 @@ | ||
If we use `resize` to expand a container, then the element of the container must have default constructor. |
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,54 @@ | ||
#include <list> | ||
#include <forward_list> | ||
#include <iostream> | ||
|
||
void change(std::list<int> &li) { | ||
for (auto iter = li.begin(); iter != li.end(); ) | ||
if (*iter % 2) { | ||
iter = li.insert(iter, *iter); | ||
++iter; ++iter; | ||
//iter += 2; // Error: list doesn't support iterator arithmetic | ||
} else | ||
iter = li.erase(iter); | ||
} | ||
|
||
void change(std::forward_list<int> &fli) { | ||
for (auto pre = fli.before_begin(), cur = fli.begin(); | ||
cur != fli.end(); ) { | ||
if (*cur % 2) { | ||
pre = fli.insert_after(pre, *cur); | ||
++pre; | ||
++cur; | ||
} else | ||
cur = fli.erase_after(pre); | ||
} | ||
} | ||
|
||
int main() { | ||
std::list<int> li{1, 2, 3, 4, 5, 6}; | ||
std::forward_list<int> fli{1, 2, 3, 4, 5, 6}; | ||
|
||
std::cout << "li:\n"; | ||
for (const auto & i : li) | ||
std::cout << i << " "; | ||
std::cout << std::endl; | ||
|
||
change(li); | ||
|
||
for (const auto & i : li) | ||
std::cout << i << " "; | ||
std::cout << std::endl; | ||
|
||
std::cout << "fli:\n"; | ||
for (const auto & i : fli) | ||
std::cout << i << " "; | ||
std::cout << std::endl; | ||
|
||
change(fli); | ||
|
||
for (const auto & i : fli) | ||
std::cout << i << " "; | ||
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 @@ | ||
It is not legal. The order of evaluation of the arguments in function `insert` is undefined, so that if the second argument is evalated first, then the program logic will be wrong. |
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,19 @@ | ||
#include <vector> | ||
using std::vector; | ||
|
||
int main() { | ||
vector<int> v{1, 2, 3, 4, 5}; | ||
|
||
auto begin = v.begin(); | ||
while (begin != v.end()) { | ||
++begin; | ||
begin = v.insert(begin, 42); | ||
//v.insert(begin, 42); | ||
// Iterator `begin` will become invalid after insert, thus if we don't | ||
// update the iterator, any usage of this iterator will have undefined | ||
// behaviours. | ||
++begin; | ||
} | ||
|
||
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 @@ | ||
#include <vector> | ||
|
||
int main() { | ||
//std::vector<int> vi{1, 2, 3, 4}; | ||
std::vector<int> vi{2, 4}; | ||
|
||
// If the container contains any odd values, the loop will continue | ||
// infinitely. | ||
auto iter = vi.begin(); | ||
while (iter != vi.end()) { // The loop body should be a block. | ||
if (*iter % 2) | ||
iter = vi.insert(iter, *iter); | ||
++iter; | ||
} | ||
|
||
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,3 @@ | ||
The `capacity` of a vector is how many elements the vector **can hold**. | ||
|
||
The `size` of a vector is how many elements the vector **already holds**. |
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 @@ | ||
No. |
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 @@ | ||
A `list` does not support random access, and element of `list` is stored seperately in memory. There is no need to reallocate its elements, and thus no need to preallocate memory. So the "`capacity`" of a `list` is the same with its `size`. | ||
|
||
An `array` has a fixed size, there is also no need to reallocate its elements, and thus no need to preallocate memory. So the "`capacity`" of an `array` is the same with its `size` too. |
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,23 @@ | ||
#include <vector> | ||
#include <iostream> | ||
|
||
int main() { | ||
std::vector<int> vi; | ||
std::cout << "Size: " << vi.size() | ||
<< "\tCapacity : " << vi.capacity() << std::endl; | ||
|
||
vi.push_back(1); | ||
std::cout << "Size: " << vi.size() | ||
<< "\tCapacity : " << vi.capacity() << std::endl; | ||
|
||
for (std::vector<int>::size_type ix = 0; ix != 100; ++ix) | ||
vi.push_back(ix); | ||
std::cout << "Size: " << vi.size() | ||
<< "\tCapacity : " << vi.capacity() << std::endl; | ||
|
||
vi.shrink_to_fit(); | ||
std::cout << "Size: " << vi.size() | ||
<< "\tCapacity : " << vi.capacity() << 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,9 @@ | ||
vector<string> svec; | ||
svec.reserve(1024); // Preallocate memory for 1024 `string`s | ||
string word; | ||
while (cin >> word) // Read stirngs into `svec` | ||
svec.push_back(word); | ||
svec.resize(svec.size()+svec.size()/2); | ||
// Reallocate memory, if current capacity is greater then this argument, | ||
// nothing happened, else expand the size to at least the same as the | ||
// argument. |
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,7 @@ | ||
If the program reads 256 words, the `capacity` is 1024. | ||
|
||
If the program reads 512 words, the `capacity` is 1024. | ||
|
||
If the program reads 1000 words, the `capacity` is 1024. | ||
|
||
If the program reads 1048 words, the `capacity` is *at least* 1048. |
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,12 @@ | ||
#include <vector> | ||
#include <string> | ||
#include <iostream> | ||
|
||
int main() { | ||
std::vector<char> vc{'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}; | ||
std::string str(vc.cbegin(), vc.cend()); | ||
|
||
std::cout << str << 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 @@ | ||
We can call `s.reserve(100)` to preallocate the space for the string `s`. |
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,39 @@ | ||
#include <string> | ||
#include <iostream> | ||
|
||
void replaceStr(std::string &s, | ||
const std::string &oldVal, | ||
const std::string &newVal) { | ||
// Use `<` operator, because there is possibility that `it` jump over `end()` | ||
for (auto it = s.begin(); it < s.end() - oldVal.size() + 1; ) { | ||
auto it2 = oldVal.cbegin(); | ||
for (auto it3 = it; it2 != oldVal.cend(); ++it2, ++it3) | ||
if (*it3 != *it2) | ||
break; | ||
if (it2 == oldVal.cend()) { | ||
std::string::size_type pos = it - s.begin(); | ||
s.erase(pos, oldVal.size()); | ||
s.insert(pos, newVal); | ||
// Recalculate `it` from `begin()` rather than use `+=` operator, because | ||
// `it` is invalid by `erase()` and `insert()` | ||
it = s.begin() + pos + newVal.size(); | ||
} else | ||
++it; | ||
} | ||
} | ||
|
||
int main() { | ||
std::string s{"r u ok?\ngo thru\ntho tho altho\nthrough thruu"}; | ||
|
||
std::cout << "Old:\n" << s << std::endl; | ||
replaceStr(s, "tho", "though"); | ||
std::cout << "\nNew:\n" << s << std::endl; | ||
replaceStr(s, "thru", "through"); | ||
std::cout << "\nNew:\n" << s << std::endl; | ||
replaceStr(s, "hl", "hello"); | ||
std::cout << "\nNew:\n" << s << std::endl; | ||
replaceStr(s, "u", "you"); | ||
std::cout << "\nNew:\n" << s << 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,31 @@ | ||
#include <string> | ||
#include <iostream> | ||
|
||
void replaceStr(std::string &s, | ||
const std::string &oldVal, | ||
const std::string &newVal) { | ||
// Use `<` operator, because it is possible that `pos` jumps over the end | ||
for (std::string::size_type pos = 0; pos < s.size(); ) { | ||
if (s.substr(pos, oldVal.size()) == oldVal) { | ||
s.replace(pos, oldVal.size(), newVal); | ||
pos += newVal.size(); | ||
} else | ||
++pos; | ||
} | ||
} | ||
|
||
int main() { | ||
std::string s{"r u ok?\ngo thru\ntho tho altho\nthrough thruu"}; | ||
|
||
std::cout << "Old:\n" << s << std::endl; | ||
replaceStr(s, "tho", "though"); | ||
std::cout << "\nNew:\n" << s << std::endl; | ||
replaceStr(s, "thru", "through"); | ||
std::cout << "\nNew:\n" << s << std::endl; | ||
replaceStr(s, "hl", "hello"); | ||
std::cout << "\nNew:\n" << s << std::endl; | ||
replaceStr(s, "u", "you"); | ||
std::cout << "\nNew:\n" << s << 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,21 @@ | ||
#include <string> | ||
#include <iostream> | ||
|
||
std::string fixName(const std::string &name, | ||
const std::string &prefix, | ||
const std::string &postfix) { | ||
std::string newName = name; | ||
std::string pref = prefix + " "; | ||
newName.insert(newName.begin(), pref.begin(), pref.end()); | ||
return newName.append(" " + postfix); | ||
} | ||
|
||
int main() { | ||
std::cout << fixName("James", "Mr.", "Jr.") << std::endl; | ||
|
||
std::string name, prefix, postfix; | ||
std::cin >> name >> prefix >> postfix; | ||
std::cout << fixName(name, prefix, postfix) << 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,24 @@ | ||
#include <string> | ||
#include <iostream> | ||
|
||
std::string fixName(const std::string &name, | ||
const std::string &prefix, | ||
const std::string &postfix) { | ||
// An easy way. | ||
//std::string newName = prefix + " " + name + " " + postfix; | ||
//return newName; | ||
|
||
std::string newName = name; | ||
newName.insert(0, prefix + " "); | ||
return newName.insert(newName.size(), " " + postfix); | ||
} | ||
|
||
int main() { | ||
std::cout << fixName("James", "Mr.", "Jr.") << std::endl; | ||
|
||
std::string name, prefix, postfix; | ||
std::cin >> name >> prefix >> postfix; | ||
std::cout << fixName(name, prefix, postfix) << std::endl; | ||
|
||
return 0; | ||
} |
Oops, something went wrong.