本书为Primer C++ 中文第五版
练习题笔记
(10.1)
void test1() {
vector<int> ive = {0, 1, 2, 3, 4, 4, 4, 5};
int val;
while(cin >> val && val != 99) {
cout << count(ive.begin(), ive.end(), val) << endl;
}
}
(10.2)
void test2() {
list<string> ive = {"a", "aa", "aaa", "a", "aa", "a", "b", "c"};
string val;
while(cin >> val && val != "q") {
cout << count(ive.begin(), ive.end(), val) << endl;
}
}
(10.3)
void test3() {
vector<double> ive = {0, 1, 2, 3, 4, 4, 4, 5.8};
cout << accumulate(ive.begin(), ive.end(), 0) << endl;
}
(10.4)
用0的话,则表明结果将会删除小数位。
所以最好是要设置小数位
(10.5)
equal是利用是使用==比较两个元素。
string重载了==,可以比较两个字符串是否等长且其中对应元素相等。
而C风格字符串
1如果是char*类型,没有影响。
2如果是char []类型,用==比较两个对象,会检查两个指针值是否相等,也就是地址是否相等。
(10.6)
void test6() {
vector<int> ive(10);
fill_n(ive.begin(), ive.size(), 0);
for(auto i : ive) {
cout << i << " ";
}
cout << endl;
}
(10.7)
a:
//使用copy等算法的时候,确保目的容器至少包含于输入序列一样多的元素。
void test7() {
list<int> lst; int i;
while(cin >> i && i != 0)
lst.push_back(i);
vector<int> vec(lst.size());
copy(lst.cbegin(), lst.cend(), vec.begin());
for(auto i : vec) {
cout << i << " ";
}
cout << endl;
}
或者
void test7() {
list<int> lst; int i;
while(cin >> i && i != 0)
lst.push_back(i);
vector<int> vec;
copy(lst.cbegin(), lst.cend(), back_inserter(vec));
for(auto i : vec) {
cout << i << " ";
}
cout << endl;
}
b:
void test7_2() {
vector<int> vec;
//reserve预留空间,没有创建元素对象
//resize改变容器大小,并且创建对象
vec.resize(10);
fill_n(vec.begin(), 10, 0);
for(auto i : vec) {
cout << i << " ";
}
cout << endl;
}
或者使用back_inserter(vec);
(10.8)
标准库算法不直接操作容器,而是通过操作迭代器间接访问容器。是否能插入删除元素,取决于传递给这些算法的迭代器是否具有这样的能力。
(10.9)
void test9() {
vector<string> sve = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
sort(sve.begin(), sve.end());
auto end_unique = unique(sve.begin(), sve.end());
sve.erase(end_unique, sve.end());
for(auto i : sve) {
cout << i << " ";
}
cout << endl;
}
(10.10)
做到算法和数据结构的分离。
算法不操作具体的容器,只操作迭代器,然后由迭代器实现对容器的访问。
这样做的目的就是实现算法的通用性。
(10.11)
bool isShorter(const string &s1, const string &s2) {
return s1.size() < s2.size();
}
void test11() {
vector<string> sve = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
sort(sve.begin(), sve.end());
auto end_unique = unique(sve.begin(), sve.end());
sve.erase(end_unique, sve.end());
for(auto i : sve) {
cout << i << " ";
}
cout << endl;
sort(sve.begin(), sve.end(), isShorter);
for(auto i : sve) {
cout << i << " ";
}
cout << endl;
}
(10.12)
struct Sales_data {
string bookNo;
Sales_data(string bn) {
bookNo = bn;
};
string isbn() {
return bookNo;
};
};
bool compareIsbn(Sales_data &sd1, Sales_data &sd2) {
return sd1.isbn().size() < sd2.isbn().size();
}
void test12() {
Sales_data book1("zl");
Sales_data book2("zzzl");
Sales_data book3("zzl");
Sales_data book4("lz");
vector<Sales_data> vsd = {book1, book2, book3, book4};
sort(vsd.begin(), vsd.end(), compareIsbn);
for(auto i : vsd) {
cout << i.bookNo << " ";
}
cout << endl;
}
(10.13)
bool sizeMore5(const string &s) {
return s.size() >= 5;
}
void test13() {
vector<string> sve = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
auto it_end = partition(sve.begin(), sve.end(), sizeMore5);
for(auto cb = sve.cbegin(); cb < it_end; cb++) {
cout << *cb << " ";
}
cout << endl;
}
(10.14)
void test14() {
auto sum = [](int a, int b){return a+b;};
cout << sum(3, 4) << endl;
}
(10.15)
void test15() {
int m =10;
auto sum = [m](int a){return a+m;};
cout << sum(5) << endl;
}
(10.16)
void biggies(vector<string> &words, vector<string>::size_type sz) {
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
stable_sort(words.begin(), words.end(),
[](const string &s1, const string &s2){return s1.size() < s2.size();});
auto wc = find_if(words.begin(), words.end(),
[sz](string &s){return s.size() >= sz;});
auto count = words.end() - wc;
cout << count << " "<< (count > 1 ? "words" : "word") << " of length "
<< sz << " or longger" << endl;
for_each(wc, words.end(), [](string &s){ cout << s << " ";});
cout << endl;
}
void test16() {
vector<string> sve = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
biggies(sve, 5);
}
(10.17)
void test17() {
Sales_data book1("zl");
Sales_data book2("zzzl");
Sales_data book3("zzl");
Sales_data book4("lz");
vector<Sales_data> vsd = {book1, book2, book3, book4};
sort(vsd.begin(), vsd.end(),
[](Sales_data &sd1, Sales_data &sd2){return sd1.isbn().size() < sd2.isbn().size();});
for(auto i : vsd) {
cout << i.bookNo << " ";
}
cout << endl;
}
(10.18)
void test18(){
vector<string> words = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
int sz = 5;
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
stable_sort(words.begin(), words.end(),
[](const string &s1, const string &s2){return s1.size() < s2.size();});
auto wc = partition(words.begin(), words.end(),
[sz](string &s){return s.size() < sz;});
auto count = words.end() - wc;
cout << count << " "<< (count > 1 ? "words" : "word") << " of length "
<< sz << " or longger" << endl;
for_each(wc, words.end(), [](string &s){ cout << s << " ";});
cout << endl;
}
(10.19)
void test19(){
vector<string> words = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
int sz = 5;
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
stable_sort(words.begin(), words.end(),
[](const string &s1, const string &s2){return s1.size() < s2.size();});
auto wc = stable_partition(words.begin(), words.end(),
[sz](string &s){return s.size() < sz;});
auto count = words.end() - wc;
cout << count << " "<< (count > 1 ? "words" : "word") << " of length "
<< sz << " or longger" << endl;
for_each(wc, words.end(), [](string &s){ cout << s << " ";});
cout << endl;
}
(10.20)
void test20() {
vector<string> words = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
auto count = count_if(words.begin(), words.end(),
[](const string &s){return s.size() > 6;});
cout << count << endl;
}
(10.21)
void test21() {
int m = 5;
auto b = [&m]()->bool{return --m;};
while(b());
cout << m << endl;
}
(10.22)
bool shorterThan(const string &s, int l) {
return s.size() <= l;
}
void test22() {
vector<string> words = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
auto count = count_if(words.begin(), words.end(),
bind(shorterThan, placeholders::_1, 6));
cout << count << endl;
}
(10.23)
bind接受的参数与它绑定的函数相关,函数接受n个参数,则bind接受n+1个参数
(10.24)
bool shorter(const string &s, int l) {
return s.size() < l;
}
void test24() {
vector<int> ive = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
string s;
while(cin >> s && s != "q") {
auto iter = find_if(ive.begin(), ive.end(), bind(shorter, s, placeholders::_1));
if(iter != ive.end()) cout << *iter << endl;
}
}
(10.25)
bool check_size(const string &s, int l) {
return s.size() >= l;
}
void test25() {
vector<string> words = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
words.erase(end_unique, words.end());
stable_sort(words.begin(), words.end(),
[](const string &s1, const string &s2){return s1.size() < s2.size();});
auto wc = find_if(words.begin(), words.end(), bind(check_size, placeholders::_1, 5));
auto count = words.end() - wc;
cout << count << " "<< (count > 1 ? "words" : "word") << " of length 5 or longger" << endl;
for_each(wc, words.end(), [](string &s){ cout << s << " ";});
cout << endl;
}
(10.26)
back_inserter 创建一个使用push_back的迭代器
front_inserter 穿件一个使用push_front的迭代器
inserter 创建一个使用insert的迭代器,此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器。元素将被插入到给定迭代器所表示的元素之前。
在使用back_inserter和front_inserter的时候要确保容器支持push_back和push_front。
(10.27)
void test27() {
vector<int> ive = {1, 2, 2, 3, 3, 3, 4, 5};
list<int> lst;
unique_copy(ive.begin(), ive.end(), inserter(lst, lst.begin()));
for(auto i : lst) cout << i << " ";
cout << endl;
}
(10.28)
void test28() {
vector<int> ori = {1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int> ive, bve;
list<int> fve;
copy(ori.rbegin(), ori.rend(), front_inserter(fve));
copy(ori.begin(), ori.end(), back_inserter(bve));
copy(ori.begin(), ori.end(), inserter(ive, ive.begin()));
for(auto i : fve) cout << i << " ";
cout << endl;
for(auto i : bve) cout << i << " ";
cout << endl;
for(auto i : ive) cout << i << " ";
cout << endl;
}
(10.29)
void test29() {
ifstream in("test.txt");
istream_iterator<string> str_it(in), end;
ostream_iterator<string> out_iter(cout, " ");
copy(str_it, end, out_iter);
cout << endl;
}
(10.30)
void test30() {
istream_iterator<int> in(cin), eof;
ostream_iterator<int> out(cout, " ");
vector<int> ive(in, eof);
sort(ive.begin(), ive.end());
copy(ive.begin(), ive.end(), out);
}
(10.31)
void test31() {
istream_iterator<int> in(cin), eof;
ostream_iterator<int> out(cout, " ");
vector<int> ive(in, eof);
sort(ive.begin(), ive.end());
unique_copy(ive.begin(), ive.end(), out);
}
(10.32)
struct Sale_data {
string bookNo;
double price;
int num;
};
istream &operator>>(istream &is, Sale_data &item) {
is >> item.bookNo >> item.price >> item.num;
return is;
}
ostream &operator<<(ostream &os,const Sale_data &item) {
os << item.bookNo << " " << item.price << " " << item.num;
return os;
}
bool compareIsbn(const Sale_data &sd1, const Sale_data &sd2) {
return sd1.bookNo.size() < sd2.bookNo.size();
}
void test32() {
istream_iterator<Sale_data> in(cin), eof;
ostream_iterator<Sale_data> out(cout, "\n");
vector<Sale_data> sve(in, eof);
copy(sve.begin(), sve.end(), out);
sort(sve.begin(), sve.end(), compareIsbn);
copy(sve.begin(), sve.end(), out);
}
(10.33)
void oddEven(const string &in, const string &odd, const string &even) {
ifstream fin(in);
ofstream foutodd(odd);
ofstream fouteven(even);
istream_iterator<int> i(fin), eof;
ostream_iterator<int> oodd(foutodd, "\n");
ostream_iterator<int> oeven(fouteven, "\n");
while(i != eof) {
if(*i%2) oodd = *i;
else oeven = *i;
i++;
}
}
void test33() {
oddEven("num.txt", "odd.txt", "even.txt");
}
(10.34)
void test34() {
ifstream fin("num.txt");
istream_iterator<int> in(fin), eof;
vector<int> ive(in, eof);
for(auto rbe = ive.crbegin(); rbe < ive.crend(); ++rbe) {
cout << *rbe << " ";
}
cout << endl;
}
(10.35)
void test35() {
ifstream fin("num.txt");
istream_iterator<int> in(fin), eof;
vector<int> ive(in, eof);
for(auto end = ive.cend() - 1; end >= ive.cbegin(); --end) {
cout << *end << " ";
}
cout << endl;
}
(10.36)
void test36() {
list<int> lst = {0, 1, 2, 3, 0, 1, 2, 0, 2, 3, 0, 4};
auto last = find(lst.crbegin(), lst.crend(), 0);
cout << *last << *last.base() << endl;
}
(10.37)
void test37() {
vector<int> ive = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
list<int> lst(ive.crbegin()+2, ive.crend()-3);
for(auto i : lst) cout << i << " ";
cout << endl;
}
(10.38)
输入迭代器,find和accumulate要求输入迭代器,istream_iterator是一种输入迭代器
输出迭代器,copy函数的第三个参数就是输出迭代器,ostream_iterator类型也是输出迭代器
前向迭代器,replace要求前向迭代器,forward_list上的迭代器是前向迭代器
双向迭代器,reverse要求双向迭代器,处理forward_list,其他标准库都提供符合双向迭代器要求的迭代器
随机访问迭代器,sort要求随机访问迭代器,array、deque、string和vector的迭代器都是随机访问迭代器,用于访问内置数组元素的指针也是。
(10.39)
list上的迭代器属于双向迭代器
vector上的迭代器属于随机访问迭代器
(10.40)
copy要求输出迭代器
reverse要求双向迭代器
unique要求前向迭代器
(10.41)
replace 把迭代器范围内的old_val替换成new_val
replace_if 把迭代器范围内使得pred为true的值替换成new_val
replace_copy 和 replace() 做的事是一样的,但它的结果会被保存到另一个序列中,而不会改变原始序列
replace_copy_if(),它和 replace_if() 算法是相同的,但它的结果会被保存到另一个序列中
void test42() {
list<string> lst = {"the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"};
lst.sort();
lst.unique();
for(auto s : lst) cout << s << " "; cout << endl;
}