C ++ Primer(第五版)第十章练习答案

本篇解析了C++ Primer第五版第十章的练习,涉及算法如count、accumulate、fill_n、unique、sort、partition等在处理vector和list以及string等不同类型数据结构中的应用。通过实例展示了如何使用这些算法解决实际问题,包括元素计数、求和、去重、排序和区间划分等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

10.1 节练习

练习 10.1

头文件 algorithm 中定义了一个名为 count 的函数,它类似 find,接受一对迭代器和一个值作为参数。count 返回给定值在序列中出现的次数。编写程序,读取 int 序列存入 vector 中,打印有多少个元素的值等于给定值。

#include<iostream>
#include<algorithm>
#include<vector>

using std::cout;
using std::endl;
using std::vector;

int main()
{
    vector<int> iv{0, 1, 2, 3, 4, 2, 3, 1, 2, 4, 3, 1, 2, 1, 5, 3, 1};

    cout << count(iv.cbegin(), iv.cend(), 1) << endl;
    return 0;
}

练习 10.2

重做上一题,但读取 string 序列存入 list 中。

#include<iostream>
#include<algorithm>
#include<list>
#include<string>

using std::cout;
using std::endl;
using std::list;
using std::string;

int main()
{
    list<string> sl{"a", "b", "c", "a"};

    cout << count(sl.cbegin(), sl.cend(), "a") << endl;
    
    return 0;
}

10.2.1 节练习

练习 10.3

用 accumulate 求一个vector< int >中的元素之和。

#include<iostream>
#include<vector>
#include<numeric>

using std::accumulate;
using std::cout;
using std::endl;
using std::vector;

int main()
{
    vector<int> iv(10, 2);

    int sum = accumulate(iv.cbegin(), iv.cend(), 0);

    cout << "和为: " << sum << endl;
    return 0;
}

练习 10.4

假定 v 是一个vector< double >,那么调用 accumulate(v.cbegin(),v.cend(),0) 有何错误(如果存在的话)?

每次计算的结果会转换为 int 而丢失精度!

练习 10.5

在本节对名册(roster)调用 equal 的例子中,如果两个名册中保存的都是 C 风格字符串而不是 string,会发生什么?

可以正常运行。

10.2.2 节练习

练习 10.6

编写程序,使用 fill_n 将一个序列中的 int 值都设置为 0。

#include<iostream>
#include<vector>

using std::cout;
using std::endl;
using std::fill_n;
using std::vector;

int main()
{
    vector<int> iv(10, 2);
    fill_n(iv.begin(), iv.size(), 0);

    for(const auto i:iv)
    {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

练习 10.7

下面程序是否有错误?如果有,请改正:

(a) 
vector<int> vec; list<int> lst; int i;
while (cin >> i)
    lst.push_back(i);
copy(lst.cbegin(), lst.cend(), vec.begin());
(b)
vector<int> vec;
vec.reserve(10);
fill_n(vec.begin(), 10, 0);

(a)错误。vec 是空容器不能拷贝。修改为:

copy(lst.cbegin(), lst.cend(), back_inserter(vec));

(b)错误。同上,空容器不能添加元素。修改为:

fill_n(back_inserter(vec), 10, 0);

练习 10.8

本节提到过,标准库算法不会改变它们所操作的容器的大小。为什么使用 back_inserter 不会使这一断言失效?

对于标准库算法而言,它只会使用赋值算法将容器内的值改变。而当标准库算法使用 back_inserter 时,赋值运算符将变作调用 push_back 函数,而非原本的赋值函数。可见这一行为是因为使用了 back_inserter 才导致改变了容器的大小,对于标准库算法而言仅仅是调用了赋值算法而已,因此不会使这一断言失效。

10.2.3 节练习

练习 10.9

实现你自己的 elimDups。测试你的程序,分别在读取输入后、调用 unique 后以及调用 erase 后打印 vector 的内容。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using std::cout;
using std::endl;
using std::sort;
using std::string;
using std::unique;
using std::vector;

void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

int main()
{
    vector<string> sv = {"c", "s", "a", "c", "a", "b", "b", "a"};
    elimDups(sv);

    for(const auto s:sv)
    {
        cout << s << " ";
    }
    cout << endl;

    return 0;
}

练习 10.10

你认为算法不改变容器大小的原因是什么?

改变容器大小可能会导致迭代器失效,而且每种容器都有自己的特性,改变容器大小可能需要使用不同的方法,不改变容器大小使得算法更加通用。

10.3.1 节练习

练习 10.11

编写程序,使用 stable_sort 和 isShorter 将传递给你的 elimDups 版本的 vector 排序。打印 vector 的内容,验证你的程序的正确性。

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>

using std::cout;
using std::endl;
using std::sort;
using std::stable_sort;
using std::string;
using std::unique;
using std::vector;

void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

bool isShorter (const string &s1, const string &s2)
{
    return s1.size() < s2.size();
}

int main()
{
    vector<string> words{"fox", "jumps", "over", "quick", "red", "red", "slow", "the", "the", "turle"};
    elimDups(words);
    stable_sort(words.begin(), words.end(), isShorter);
    for(const auto &s:words)
    {
        cout << s << " ";
    }
    cout << endl;
    return 0;
}

练习 10.12

编写名为 compareIsbn 的函数,比较两个 Sales_data 对象的 isbn( ) 成员。使用这个函数排序一个保存 Sales_data 对象的 vector。

#include<iostream>
#include"Sales_data.h"
#include<algorithm>
#include<vector>
#include<sstream>
#include<fstream>

using std::ifstream;
using std::sort;
using std::vector;
using std::stable_sort;

bool compareIsbn(const Sales_data &sd1, const Sales_data &sd2)
{
    return sd1.isbn() < sd2.isbn();
}

int main()
{
    vector<Sales_data> sdvs;
    ifstream in("sd.txt");
    if (in)
    {
        string line;
        while (getline(in,line))
        {
            sdvs.push_back(line);
        }

        stable_sort(sdvs.begin(), sdvs.end(), compareIsbn);

        for(const auto &a:sdvs)
        {
            cout << a.isbn() << endl;
        }
    }
    else
    {
        std::cerr << "无法打开文件!" << endl;
    }
    
    return 0;
}

练习 10.13

标准库定义了名为 partition 的算法,它接受一个谓词,对容器内容进行划分,使得谓词为 true 的值会排在容器的前半部分,而使得谓词为 false 的值会排在后半部分。算法返回一个迭代器,指向最后一个使谓词为 true 的元素之后的位置。编写函数,接受一个 string,返回一个 bool 值,指出 string 是否有 5 个或更多字符。使用此函数划分 words。打印出长度大于等于 5 的元素。

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;

bool isFiveWords(const string &str)
{
    return str.size() > 4;
}

int main()
{
    vector<string> words{"fox", "jumps", "over", "quick", "red", "red", "slow", "the", "the", "turle"};
    auto iter = std::partition(words.begin(), words.end(), isFiveWords);

    words.erase(iter, words.end());
    for(const auto &s:words)
    {
        cout << s << " ";
    }
    cout << endl;
    return 0;
}

10.3.2 节练习

练习 10.14

编写一个 lambda ,接受两个 int,返回它们的和。

#include<iostream>

using std::cout;
using std::endl;

int main()
{
    auto func = [](int x, int y) { return x + y; };
    cout << func(1, 2) << endl;
    return 0;
}

练习 10.15

编写一个 lambda ,捕获它所在函数的 int,并接受一个 int 参数。lambda 应该返回捕获的 int 和 int 参数的和。

#include<iostream>

using std::cout;
using std::endl;

int main()
{
    int a = 2;
    auto func = [a](int i) { return i + a; };
    cout << func(3) << endl;

    return 0;
}

练习 10.16

使用 lambda 编写你自己版本的 biggies。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

string make_plural(size_t ctr, const string &word, const string &ending)
{
    return (ctr > 1) ? word + ending : word;
}

void biggies(vector<string> &words, vector<string>::size_type sz)
{
    elimDups(words);
    stable_sort(words.begin(), words.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
    auto wc = find_if(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });
    auto count = words.end() - wc;
    cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
}


int main()
{
    vector<string> words{"fox", "jumps", "over", "quick", "red", "red", "slow", "the", "the", "turle"};
    biggies(words, 4);
    return 0;
}

练习 10.17

重写 10.3.1 节练习 10.12(第 345 页)的程序,在对 sort 的调用中使用 lambda 来代替函数 compareIsbn。

#include<iostream>
#include"Sales_data.h"
#include<algorithm>
#include<vector>
#include<sstream>
#include<fstream>

using std::ifstream;
using std::sort;
using std::vector;
using std::stable_sort;


int main()
{
    vector<Sales_data> sdvs;
    ifstream in("sd.txt");
    if (in)
    {
        string line;
        while (getline(in,line))
        {
            sdvs.push_back(line);
        }

        stable_sort(sdvs.begin(), sdvs.end(), [](const Sales_data &sd1, const Sales_data &sd2) { return sd1.isbn() < sd2.isbn(); });

        for(const auto &a:sdvs)
        {
            cout << a.isbn() << endl;
        }
    }
    else
    {
        std::cerr << "无法打开文件!" << endl;
    }
    
    return 0;
}

练习 10.18

重写 biggies,用 partition 代替 find_if。我们在10.3.1节练习10.13(第345页)中介绍了 partition 算法。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

string make_plural(size_t ctr, const string &word, const string &ending)
{
    return (ctr > 1) ? word + ending : word;
}

void biggies(vector<string> &words, vector<string>::size_type sz)
{
    elimDups(words);
    stable_sort(words.begin(), words.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
    auto wc = partition(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });
    // 结果和 find_if 刚好相反,是吧判断条件为 true 的元素排到前面,指向 ture 元素的下一个元素
    for(const auto s:words)
    {
        cout << s << " ";
    }
    cout << endl;

    auto count = wc - words.begin();
    cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
}


int main()
{
    vector<string> words{"fox", "jumps", "over", "quick", "red", "red", "slow", "the", "the", "turle"};
    biggies(words, 4);
    return 0;
}

练习 10.19

用 stable_partition 重写前一题的程序,与 stable_sort 类似,在划分后的序列中维持原有元素的顺序。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>

using namespace std;

void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

string make_plural(size_t ctr, const string &word, const string &ending)
{
    return (ctr > 1) ? word + ending : word;
}

void biggies(vector<string> &words, vector<string>::size_type sz)
{
    elimDups(words);
    stable_sort(words.begin(), words.end(), [](const string &a, const string &b) { return a.size() < b.size(); });

    for(const auto s:words)
    {
        cout << s << " ";
    }
    cout << endl;

    auto wc =stable_partition(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });

    for(const auto s:words)
    {
        cout << s << " ";
    }
    cout << endl;

    auto count = wc - words.begin();
    cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
}


int main()
{
    vector<string> words{"fox", "jumps", "over", "quick", "red", "red", "slow", "the", "the", "turle"};
    biggies(words, 4);
    return 0;
}

使用 partition 函数前后顺序

fox red the over slow jumps quick turle
(turle quick jumps over slow) (the red fox)

使用 stable_partition 函数前后顺序

fox red the over slow jumps quick turle
(over slow jumps quick turle) (fox red the)

true 和 false 两组中的元素相对顺序不变!

10.3.4 节练习

练习 10.20

标准库定义了一个名为 count_if 的算法。类似 find_if,此函数接受一对迭代器,表示一个输入范围,还接受一个谓词,会对输入范围中每个元素执行。count_if 返回一个计数值,表示谓词有多少次为真。使用 count_if 重写我们程序中统计有多少单词长度超过6的部分。

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>

using namespace std;

int main()
{
    vector<string> words{"a", "a", "aa", "aaa", "aa", "a", "aaaaaa", "aaaaaaa", "aaa", "aaaaaa"};
    string::size_type sz = 6;

    auto count = count_if(words.begin(), words.end(), [sz](const string &a) { return a.size() > sz; });

    cout <<"长度超过 6 的单词有 "<< count <<" 个!"<< endl;
    return 0;
}

练习 10.21

编写一个 lambda,捕获一个局部 int 变量,并递减变量值,直至它变为 0。一旦变量变为 0,再调用 lambda 应该不再递减变量。lambda 应该返回一个 bool 值,指出捕获的变量是否为0。

#include<iostream>

using std::cout;
using std::endl;

int main()
{
    int a = 5;

    auto res = [&a]() -> bool
    {
        if (a <= 0)
        {
            return false;
        }
        else
        {
            --a;
            return true;
        }
    };

    while (res())
    {
        cout << a << endl;
    }

    return 0;
}

10.3.4 节练习

练习 10.22

重写统计长度小于等于 6 的单词数量的程序,使用函数代替 lambda。

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<functional>

using namespace std;
using namespace std::placeholders;

bool isSix(const string &a, string::size_type i)
{
    return a.size() > i;
}

int main()
{
    vector<string> words{"a", "a", "aa", "aaa", "aa", "a", "aaaaaa", "aaaaaaa", "aaa", "aaaaaa"};
    string::size_type sz = 6;

    auto count = count_if(words.begin(), words.end(), bind(isSix, _1, sz));

    cout <<"长度超过 6 的单词有 "<< count <<" 个!"<< endl;
    return 0;
}

练习 10.23

bind 接受几个参数?

bind 接受一个函数名,和一个参数列表,参数的数量没有限制。

练习 10.24

给定一个 string,使用 bind 和 check_size 在一个 int 的 vector 中查找第一个大于 string 长度的值。

#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<algorithm>

using namespace std;
using namespace std::placeholders;

bool check_size(const string &s, string::size_type sz)
{
    return s.size() < sz;
}

int main()
{
    vector<int> iv{0, 1, 2, 3, 4, 5, 6};
    string word("sss");

    auto iter = find_if(iv.begin(), iv.end(), bind(check_size, word, _1));
    cout << *iter << " 的值大于 " << word << " 的长度!" << endl;
    return 0;
}

练习 10.25

在 10.3.2节(第 349 页)的练习中,编写了一个使用 partition 的 biggies 版本。使用 check_size 和 bind 重写此函数。

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>

using namespace std;

void elimDups(vector<string> &words)
{
    sort(words.begin(), words.end());
    auto end_unique = unique(words.begin(), words.end());
    words.erase(end_unique, words.end());
}

string make_plural(size_t ctr, const string &word, const string &ending)
{
    return (ctr > 1) ? word + ending : word;
}

bool check_size(const string &s, string::size_type sz)
{
    return s.size() >= sz;
}

void biggies(vector<string> &words, vector<string>::size_type sz)
{
    elimDups(words);
    stable_sort(words.begin(), words.end(), [](const string &a, const string &b) { return a.size() < b.size(); });

    auto wc = partition(words.begin(), words.end(), bind(check_size, std::placeholders::_1, sz));

    auto count = wc - words.begin();
    cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
}


int main()
{
    vector<string> words{"fox", "jumps", "over", "quick", "red", "red", "slow", "the", "the", "turle"};
    biggies(words, 4);
    return 0;
}

10.4.1 节练习

练习 10.26

解释三种插入迭代器的不同之处。

back_inserter 创建一个使用 push_back 的迭代器,将元素插入的容器末尾。接收被插入元素一个参数。

front_inserter 创建一个使用 push_front 的迭代器,将元素插入到容器头部。接收被插入元素一个参数。

inserter 创建一个使用 insert 的迭代器,将元素插入到指定位置元素之前。接收被插入元素和目标位置两个参数。

练习 10.27

除了 unique(参见 10.2.3 节,第 343 页)之外,标准库还定义了名为 unique_copy 的函数,它接受第三个迭代器,表示拷贝不重复元素的目的位置。编写一个程序,使用 unique_copy 将一个 vector 中不重复的元素拷贝到一个初始化为空的 list 中。

#include<iostream>
#include<vector>
#include<list>
#include<algorithm>

using std::cout;
using std::endl;
using std::list;
using std::vector;

> 这里是引用

int main()
{
    vector<int> iv{1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
    list<int> il;
    
    std::unique_copy(iv.cbegin(), iv.cend(), std::back_inserter(il));

    for(const auto i:il)
    {
        cout << i << " ";
    }
    cout << endl;
    return 0;
}

练习 10.28

一个vector 中保存 1 到 9,将其拷贝到三个其他容器中。分别使用inserter、back_inserter 和 front_inserter 将元素添加到三个容器中。对每种 inserter,估计输出序列是怎样的,运行程序验证你的估计是否正确。

#include<iostream>
#include<vector>
#include<list>

using std::copy;
using std::cout;
using std::endl;
using std::list;
using std::vector;

int main()
{
    vector<int> iv{1, 2, 3, 4, 5, 6, 7, 8, 9};
    list<int> il1, il2, il3;

    copy(iv.cbegin(), iv.cend(), std::back_inserter(il1));
    for(const auto i:il1)
    {
        cout << i << " ";
    }
    cout << endl;

    copy(iv.cbegin(), iv.cend(), std::front_inserter(il2));
    for(const auto i:il2)
    {
        cout << i << " ";
    }
    cout << endl;

    copy(iv.cbegin(), iv.cend(), std::inserter(il3, il3.begin()));
    for(const auto i:il3)
    {
        cout << i << " ";
    }
    cout << endl;
    
    return 0;
}

结果

back_inserter:1 2 3 4 5 6 7 8 9
front_inserter:9 8 7 6 5 4 3 2 1
inserter:1 2 3 4 5 6 7 8 9

10.4.2 节练习

练习 10.29

编写程序,使用流迭代器读取一个文本文件,存入一个 vector 中的 string 里。

#include<iostream>
#include<vector>
#include<string>
#include<fstream>
#include<iterator>

using namespace std;

int main()
{
    ifstream in("str.txt");
    vector<string> sv;
    if (in)     
    {
        istream_iterator<string> str_it(in);
        istream_iterator<string> eof;
        while (str_it!=eof)
        {
            sv.push_back(*str_it++);
        }
        for(const auto &s:sv)
        {
            cout << s << " ";
        }
        cout << endl;
    }
    else
    {
        std::cerr << "无法打开文件!" << endl;
    }
    
    return 0;
}

练习 10.30

使用流迭代器、sort 和 copy 从标准输入读取一个整数序列,将其排序,并将结果写到标准输出。

#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>

using namespace std;

int main()
{
    istream_iterator<int> int_it(cin), int_eof;
    vector<int> iv(int_it, int_eof);
    sort(iv.begin(), iv.end());
    ostream_iterator<int> out_iter(cout, " ");
    for(auto e:iv)
    {
        *out_iter++ = e;
    }
    cout << endl;
    return 0;
}

练习 10.31

修改前一题的程序,使其只打印不重复的元素。你的程序应该使用 unique_copy(参见 10.4.1节,第 359 页)。

#include<iostream>
#include<vector>
#include<iterator>
#include<algorithm>

using namespace std;

int main()
{
    istream_iterator<int> int_it(cin), int_eof;
    vector<int> iv(int_it, int_eof);
    sort(iv.begin(), iv.end());
    ostream_iterator<int> out_iter(cout, " ");

    unique_copy(iv.cbegin(), iv.cend(), out_iter);
    cout << endl;
    return 0;
}

练习 10.32

重写 1.6节(第 21 页)中的书店程序,使用一个 vector 保存交易记录,使用不同算法完成处理。使用 sort 和10.3.1节(第345页)中的 compareIsbn 函数来排序交易记录,然后使用 find 和 accumulate 求和。

#include<iostream>
#include<vector>
#include<fstream>
#include<iterator>
#include<algorithm>
#include"Sales_item.h"
#include<numeric>

using namespace std;

bool compareIsbn1(const Sales_item &lhs, const Sales_item &rhs) 
{ 
    return lhs.isbn() < rhs.isbn(); 
}

int main()
{
    istream_iterator<Sales_item> item_iter(cin), eof;
    vector<Sales_item> v1(item_iter, eof);
	sort(v1.begin(), v1.end(), compareIsbn1);

    cout << endl;
	for(auto beg = v1.cbegin(), end = beg; beg != v1.cend(); beg = end)
	{
		end = find_if(beg, v1.cend(), [beg](const Sales_item &sale_item){ return sale_item.isbn() != beg->isbn(); });
		cout << accumulate(beg, end, Sales_item(beg->isbn())) << endl;
	}

    return 0;
}

练习 10.33

编写程序,接受三个参数:一个输入文件和两个输出文件的文件名。输入文件保存的应该是整数。使用 istream_iterator 读取输入文件。使用 ostream_iterator 将奇数写入第一个输入文件,每个值后面都跟一个空格。将偶数写入第二个输出文件,每个值都独占一行。

#include<iostream>
#include<iterator>
#include<fstream>
#include<string>
#include<vector>

using namespace std;

void classify(const string &intFileName, const string &oddFileName, const string &evenFileName)
{
    ifstream in(intFileName);
    istream_iterator<int> int_it(in), int_eof;
    vector<int> iv(int_it, int_eof);

    ofstream out1(oddFileName), out2(evenFileName);
    ostream_iterator<int> iter_out1(out1, " "), iter_out2(out2, " ");
    for(auto i:iv)
    {
        if (i%2==1)
        {
            *iter_out1++ = i;
        }
        else
        {
            *iter_out2++ = i;
        }
    }
}

int main(int argc,char *argcv[])
{
    classify("int.txt", "odd.txt", "even.txt");

    return 0;
}

10.4.3 节练习

练习 10.34

使用 reverse_iterator 逆序打印一个 vector。

#include<iostream>
#include<vector>

using std::cout;
using std::endl;
using std::vector;

int main()
{
    vector<int> iv{0, 1, 2, 3, 4, 5, 6};
    for (auto r_iter = iv.crbegin(); r_iter != iv.crend();++r_iter)
    {
        cout << *r_iter << " ";
    }
    cout << endl;
    return 0;
}

练习 10.35

使用普通迭代器逆序打印一个 vector。

#include<iostream>
#include<vector>

using std::cout;
using std::endl;
using std::vector;

int main()
{
    vector<int> iv{0, 1, 2, 3, 4, 5, 6};
    for (auto iter = iv.cend() - 1; iter != iv.cbegin() - 1;--iter)
    {
        cout << *iter << " ";
    }
    cout << endl;
    return 0;
}

练习 10.36

使用 find 在一个 int 的 list 中查找最后一个值为 0 的元素。

#include<iostream>
#include<vector>
#include<algorithm>

using std::cout;
using std::endl;
using std::find;
using std::vector;

int main()
{
    vector<int> iv{0, 1, 2, 3, 4, 5, 0, 6, 7};
    auto r_iter = find(iv.crbegin(), iv.crend(), 0);
    cout << *r_iter << endl;
    return 0;
}

练习 10.37

给定一个包含 10 个元素的 vector,将位置 3 到 7 之间的元素按逆序拷贝到一个 list 中。

#include<iostream>
#include<vector>
#include<list>
#include<iterator>

using std::copy;
using std::cout;
using std::endl;
using std::list;
using std::vector;

int main()
{
    vector<int> iv{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    list<int> il;
    copy(iv.crbegin() + 2, iv.crbegin() + 7, std::back_inserter(il));
    for(auto i:il)
    {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

10.5.1 节练习

练习 10.38

列出 5 个迭代器类别,以及每类迭代器所支持的操作。

输入迭代器(input iterator):

iter1 == iter2; iter1 != iter2;
++iter; iter++;
*iter;
iter->member; (*iter).member;

输出迭代器(output iterator):

++iter; iter++;
*iter;

前向迭代器(forward iterator):

iter1 == iter2; iter1 != iter2;
++iter; iter++;
*iter;
iter->member; (*iter).member;

双向迭代器(bidirectional iterator):

iter1 == iter2; iter1 != iter2;
++iter; iter++;
--iter; iter--;
*iter;
iter->member; (*iter).member;

随机访问迭代器(random-access iterator):

iter1 == iter2; iter1 != iter2;
++iter; iter++;
--iter; iter--;
*iter;
iter->member; (*iter).member;
iter1 (<><=>=) iter2;
iter (++=--=) vlau;
iter1 - iter2;
iter[n]; (*iter[n]);

练习 10.39

list 上的迭代器属于哪类?vector 呢?

list 上是双向迭代器;
vector 上是随机访问迭代器。

练习 10.40

你认为 copy 要求哪类迭代器?reverse 和 unique 呢?

copy 前两个为输入迭代器,最后一个为输出迭代器;

reverse 双向迭代器;

unique 前向迭代器。

10.5.3 节练习

练习 10.41

仅根据算法和参数的名字,描述下面每个标准库算法执行什么操作:

replace(beg, end, old_val, new_val);
replace_if(beg, end, pred, new_val);
replace_copy(beg, end, dest, old_val, new_val);
replace_copy_if(beg, end, dest, pred, new_val);

(1)将范围内的所有 old_val 替换成 new_val;

(2)将范围内的所有满足 pred 条件的元素替换成 new_val;

(3)将范围内的所有 old_val 替换成 new_val 的结果复制给 dest,原容器内的值不变;

(4)将范围内的所有满足 pred 条件的元素替换成 new_val 的结果复制给 dest,原容器内的值不变。

10.6 节练习

练习 10.42

使用 list 代替 vector 重新实现 10.2.3 节中的去除重复单词的程序。

#include<iostream>
#include<list>
#include<string>

using std::cout;
using std::endl;
using std::list;
using std::string;

void elimDups(list<string> &words)
{
    words.sort();
    words.unique();
}

int main()
{
    list<string> sl{"a", "a", "c", "c", "b", "b"};
    elimDups(sl);
    for(const auto &s:sl)
    {
        cout << s << " ";
    }
    cout << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值