C++ Prime第十章
练习10.1
int main()
{
vector<int> data;
int num, sum = 0;
while (cin >> num)
data.push_back(num);
cout << "输入一个要查找的值: " << endl;
int val;
cin.clear();
cin >> val;
sum = count(data.begin(), data.end(), val);
cout << "共有" << sum<< "个" << val;
return 0;
}
练习10.2
int main()
{
vector<string> data;
string num;
int sum = 0;
while (cin >> num)
data.push_back(num);
cout << "输入一个要查找的值: " << endl;
string val;
cin.clear();
cin >> val;
sum = count(data.begin(), data.end(), val);
cout << "共有" << sum<< "个" << val;
return 0;
}
练习10.3
int main()
{
vector<int> data{ 1,2,3,4,5,6,7,8,9 };
int sum = accumulate(data.begin(), data.end(), 0);
cout << sum << endl;
return 0;
}
练习10.4
第三个参数决定了加法的类型和返回值的类型,故纯在缩窄转换的错误,改为accumulate(data.begin(),data.end(),0.0)即可
练习10.5
比较C风格字符串应使用strcmp
int main()
{
vector<const char*> roster1 = { "hello nihao" };
list<const char*> roster2 = { "hello nihao" };
if (equal(roster1.cbegin(), roster1.cend(), roster2.cbegin()))
cout << "相等";
else
cout << "不等";
return 0;
}
练习10.6
int main()
{
vector<int> vec;
fill_n(back_inserter(vec), 10, 0);
list<int> ilst;
fill_n(back_inserter(ilst), 10, 0);
deque<int > ideq;
fill_n(back_inserter(ideq), 10, 0);
//forward_list<int> if_lst;
//fill_n(back_inserter(if_lst), 10, 0);
string str;
fill_n(back_inserter(str), 10, 'c');
//array<int, 10> arr;
//fill_n(back_inserter(arr), 9, 0);//bug
//stack<int> s;
//fill_n(back_inserter(s), 10, 0);
//queue<int> q;
//fill_n(back_inserter(q), 10, 0);
//priority_queue<int> pq;
//fill_n(back_inserter(pq), 10, 0);
return 0;
}
练习10.7
(a)错了,目标容器容量不足
(b)错误.reserve分配了10个元素空间.但是并未有元素,自然无法赋值.
练习10.8
因为算法依旧没改变容器的大小,改变容器大小的是迭代器.算法只是借用了这个迭代器而已.
练习10.9
void elimDups(vector<string>& words)
{
sort(words.begin(), words.end());
auto p = unique(words.begin(), words.end());//unique多余的重复元素被移动到最后,但是会被重新赋值,VS会将string类型的赋值为'\0',看书上(p.343)也是用了"???"来代替
cout << "After using unique():\n";
for (const auto& x : words) cout << x << " ";
cout << endl;
words.erase(p, words.end());
cout << "After using erase():\n";
for (const auto& x : words) cout << x << " ";
cout << endl;
}
int main()
{
cout << "Please enter strings:\n";
vector<string> words;
string w;
while (cin >> w)
words.push_back(w);
cin.clear();
for (const auto& x : words) cout << x << " ";
cout << endl;
elimDups(words);
return 0;
}
练习10.10
原因是算法对迭代器进行操作,而不直接操作容器,保证了算法的通用性.
练习10.11
void elimDups(vector<string>& words)
{
sort(words.begin(), words.end());
auto p = unique(words.begin(), words.end());
words.erase(p, words.end());
cout << "After using erase():\n";
for (const auto& x : words) cout << x << " ";
cout << endl;
}
bool isShort(const string& s1, const string& s2)
{
return s1.size() < s2.size();
}
int main()
{
cout << "Please enter strings:\n";
vector<string> words;
string w;
while (cin >> w)
words.push_back(w);
cin.clear();
elimDups(words);
stable_sort(words.begin(), words.end(), isShort);
cout << "After using stable_sort():\n";
for (const auto& x : words) cout << x << " ";
cout << endl;
return 0;
}
练习10.12
#include <iostream>
#include <vector>
#include "Sales_data.h"
#include <algorithm>
using namespace std;
bool compareIsbn(const Sales_data& s1, const Sales_data& s2)
{
return s1.isbn() < s2.isbn();
}
int main()
{
vector<Sales_data> vec{ {"xd1234",10,10},{"xd1134",11,15},{"xd1138",19,19} };
sort(vec.begin(), vec.end(), compareIsbn);
for (const auto& x : vec)
cout << x << endl;
cout << endl;
return 0;
}
练习10.13
bool is_longer_than_5(const string& s)
{
return s.size() >= 5;
}
int main()
{
vector<string> words;
string tmp;
while (cin >> tmp)
words.push_back(tmp);
cin.clear();
auto p_end = partition(words.begin(),words.end(),is_longer_than_5);
for (auto p = words.begin(); p != p_end; ++p)
cout << *p << endl;
return 0;
}
练习10.14
auto f = [](int a1, int a2) {return a1 + a2; };
cout << f(1, 2) << endl;
练习10.15
int test_fun(int a1)
{
auto f = [a1](int a2) {return a1 + a2; };
return a1 + f(2);
}
int main()
{
cout << test_fun(1) << endl;
return 0;
}
练习10.16
void biggies(vector<string>& words, vector<string>::size_type sz)
{
elimDups(words);
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](const string& a) {return a.size() > sz; });
auto count = words.end() - wc;
for_each(wc, words.end(),
[](const string& s){ cout << s << " "; });
cout << endl;
}
练习10.17
int main()
{
vector<Sales_data> vec{ {"xd1234",10,10},{"xd1134",11,15},{"xd1138",19,19} };
sort(vec.begin(), vec.end(),
[](const Sales_data& s1, const Sales_data& s2) {return s1.isbn() < s2.isbn(); });
for (const auto& x : vec)
cout << x << endl;
cout << endl;
return 0;
}
练习10.18
void biggies(vector<string>& words, vector<string>::size_type sz)
{
elimDups(words);
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](const string& a) {return a.size() > sz; });
auto count = wc - words.begin();//注意:partition返回迭代器的位置
for_each(words.begin(),wc,
[](const string& s) { cout << s << " "; });
cout << endl;
}
练习10.19
把上题partition换成stable_partition即可,其他不做更改.
练习10.20
void biggies(vector<string>& words, vector<string>::size_type sz)
{
elimDups(words);
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](const string& a) {return a.size() > sz; });
auto count = count_if(words.begin(), wc, [sz](const string& s) {return s.size() > sz; });
for_each(words.begin(),wc,
[](const string& s) { cout << s << " "; });
cout << endl;
}
练习10.21
void fun()
{
int n = 10;
auto f = [&n]()->bool {
cout << "此时n= " << n ;
if (n == 0) return true;
else {
n--;
return false;
}
};
int index = 15;
while (index--)
if (!f()) cout << ",n不为0" << endl;
else cout << ",n为0" << endl;
}
练习10.22
int n_bind = count_if(da.begin(), da.end(), bind(check_size, _1, 6));
练习10.23
至少一个,表示要绑定的函数对象,至多n+1个,n为被绑定的函数对象的参数个数
练习10.24
bool check_size(int n, const string& t)
{
string s = to_string(n);
return s.size() > t.size();
}
int main()
{
vector<int> vec{ 11111,22222,333,44444444,555,66,7,8,9999999,12012 };
string tmp;
cin >> tmp;
auto p = find_if(vec.begin(), vec.end(), bind(check_size, _1, tmp));
cout << *p << endl;
return 0;
}
练习10.25
换汤不换药
练习10.26
back_inserter: 底层调用push_back
front_inserter:调用push_front //插入是倒序
inserter:调用insert.
练习10.27
int main()
{
vector<int> vec{ 11111,22222,333,44444444,555,66,7,8,9999999,12012 ,55,11111};
list<int> empty_list;
sort(vec.begin(), vec.end());
unique_copy(vec.begin(), vec.end(), back_inserter(empty_list));
for (const auto& x : empty_list)
cout << x << " ";
return 0;
}
练习10.28
inserter和back_inserter顺序相同:1 2 3 4 5 6 7 8 9
front_inserter顺序相反:9 8 7 6 5 4 3 2 1
int main()
{
vector<int> a{ 1,2,3,4,5,6,7,8,9 };
list<int> ilst;
forward_list<int> iflst;
vector<int> ivec;
copy(a.begin(), a.end(), inserter(ilst, ilst.begin()));
copy(a.begin(), a.end(), front_inserter(iflst));
copy(a.begin(), a.end(), back_inserter(ivec));
cout << "inserter:\n";
for (auto x : ilst)
cout << x << " ";
cout << endl;
cout << "front_inserter:\n";
for (auto x : iflst)
cout << x << " ";
cout << endl;
cout << "back_inserter:\n";
for (auto x : ivec)
cout << x << " ";
cout << endl;
return 0;
}
练习10.29
int main()
{
vector<string> str_vec;
ifstream fin("word.txt");
if (!fin)
cout << "123";
istream_iterator<string> in(fin), eof;
while (in != eof)
str_vec.push_back(*in++);
fin.close();
ostream_iterator<string> out(cout, " ");
copy(str_vec.begin(), str_vec.end(), out);
return 0;
}
练习10.30
int main()
{
istream_iterator<int> in(cin),eof;
ostream_iterator<int> out(cout, " ");
vector<int> ivec;
copy(in, eof, inserter(ivec, ivec.begin()));
sort(ivec.begin(), ivec.end());
copy(ivec.begin(), ivec.end(), out);
return 0;
}
练习10.31
int main()
{
istream_iterator<int> in(cin),eof;
ostream_iterator<int> out(cout, " ");
vector<int> ivec;
copy(in, eof, inserter(ivec, ivec.begin()));
sort(ivec.begin(), ivec.end());
unique_copy(ivec.begin(), ivec.end(), out);
return 0;
}
练习10.32
啥玩意,整着一个程序做一万遍,改过来改过去.
练习10.33
void fun(const string& name1, const string& name2, const string& name3)
{
ofstream fout2(name2),fout3(name3);
ifstream fin(name1);
istream_iterator<int> in(fin), end;
ostream_iterator<int> out2(fout2," "),out3(fout3," ");
vector<int> data;
while (in != end)
data.push_back(*in++);
copy_if(data.begin(), data.end(),out2, [](int n) {return n % 2 == 0; });
copy_if(data.begin(), data.end(), out3, [](int n) {return n % 2 != 0; });
}
int main()
{
fun("numbers.txt", "奇数.txt", "偶数.txt");
return 0;
}
练习10.34
int main()
{
vector<int> data{ 1,2,3,4,5,6,7,8,9 };
vector<int>::reverse_iterator it = data.rbegin();
ostream_iterator<int> out(cout, " ");
copy(it, data.rend(), out);
return 0;
}
练习10.35
int main()
{
vector<int> data{ 1,2,3,4,5,6,7,8,9 };
ostream_iterator<int> out(cout, " ");
for (auto p = data.end() - 1; p != data.begin() ; --p)
out = *p;
out = data.front();
return 0;
}
练习10.36
int main()
{
list<int> data{ 1,2,3,4,5,6,7,0,8,9 };
ostream_iterator<int> out(cout, " ");
auto p = data.rbegin();
auto q = find(p, data.rend(), 0);
return 0;
}
练习10.37
int main()
{
vector<int> data{ 1,2,3,4,5,6,7,8,9,10};
auto re_it = data.crbegin();
advance(re_it, 3);
list<int> lst(re_it,re_it+5);
ostream_iterator<int> out(cout, " ");
copy(lst.cbegin(), lst.cend(), out);
return 0;
}
练习10.38
输入迭代器:只递增,插入.== != ++ * ->
输出迭代器:只递增,输出 ++ *
前向迭代器:只递增,输入输出 包含以上
双向迭代器:递增递减,输入输出 多了 --
随机访问迭代器:递增递减,随机访问,输入输出 += -= - []
练习10.39
list::iterator双向迭代器,vector::iterator 随机访问迭代器
练习10.40
copy前两个表示迭代器范围的迭代器应当最低是输入迭代器,第三个目的迭代器应当最低是输出迭代器
reverse:双向迭代器
练习10.41
replace(beg,end,old_val,new_val); //[beg,end)内,每个old_val替换成new_val
replace_if(beg,end,pred,new_val); //[beg,end)内,每个满足pred的元素替换成new_val
replace_copy(beg,end,dest,old_val,new_val); //[beg,end)内,每个old_val替换成new_val,存入dest开始的容器内,但是[beg,end)内不变
类似,不写了
练习10.42
void elimDups(list<int>& words)
{
words.sort();
words.unique();
}
简单高效,所以插入删除还是要选链表啊.