C++ Primer(第五版)|练习题答案与解析(第十章:泛型算法)

C++ Primer(第五版)|练习题答案与解析(第十章:泛型算法)

本博客主要记录C++ Primer(第五版)中的练习题答案与解析。
参考:C++ Primer
C++ Primer

练习题10.1

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

练习题10.2

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <list>
int main()
{
    // 练习题10.1
    std::vector<int> v = { 1, 6, 3, 6, 5, 6, 7, 8, 9 };
    std::cout << "ex 10.01: " << std::count(v.cbegin(), v.cend(), 6) << std::endl;
    // 练习题10.2
    std::list<std::string> l = { "aa", "bb", "aa", "cc" };
    std::cout << "ex 10.02: " << std::count(l.cbegin(), l.cend(), "aa") << std::endl;
    return 0;
}

测试:

ex 10.01: 3
ex 10.02: 2

练习题10.3

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;
int main()
{
    int ia[] = {1, 2, 2, 4, 3, 4, 2};
    vector<int> ivec(ia, ia+7);
    int sum = accumulate(ivec.begin(), ivec.end(), 0);
    cout << sum << endl;
    return 0;
}

输出:18

练习题10.4

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

因为第三个参数是0,则编译器会认为其是一个int类型。最后的求和会损失精度。

练习题10.5

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

引用牛客网的回答:

equal使用运算符比较两个序列中的元素。string类重载了,可比较两个字符串是否长度相等且其中元素对位相等。而C风格字符串本质是char类型,用==比较两个char对象,只是检查两个指针值是否相等,即地址是否相等,而不会比较其中字符是否相同。所以,只有当两个序列中的指针都指向相同的地址时;
equal才会返回true。否则,即使字符串内容完全相同,也会返回false。
如下面的程序,q中的每个字符串是p中字符串的拷贝,虽然内容相同,但是不同对象指向不同地址,因此equal判定它们不等。而r中每个指针都是p中指针的拷贝,指向相同的地址,因此equal判定它们相等。

练习题10.6

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

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    vector<int> vec{ 0, 1, 2, 3, 4, 5, 6};
    fill_n(vec.begin(), vec.size(), 0);
    for (auto i : vec)
        cout << i << " ";
    cout << endl;
}

测试:0 0 0 0 0 0 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()

有错误,其中vec的大小为0,如果直接将lst复制到vec,将会发生灾难性的错误(P341)。
需要在copy前加上:vec.resize(lst.size());
(b)

vector<int> vec;
vec.reserve(10);        // 有误
fill_n(vec.begin(), 10, 0);

其中reserve是改变容器容量的,并不能改变容器大小。应改为resize。

练习题10.8

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

传递的参数是back_inserter返回的迭代器,每次赋值都会调用push_back。通过插入迭代器来插入元素,使用的是迭代器,而不是算法插入(P341)。

练习题10.9

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void elimDups(vector<string>& words)
{
    sort(words.begin(), words.end());
    // 按字典序重排words
    for (auto i : words) {
        cout << i << " ";
    }
    cout << endl;
    auto end_unique = unique(words.begin(), words.end());
    // 重排,使每个单词只出现一次,指向不重复区域之后的迭代器。
    for (auto i : words) {
        cout << i << " ";
    }
    cout << endl;
    words.erase(end_unique, words.end());
    for (auto i : words) {
        cout << i << " ";
    }
    cout << endl;
}
int main()
{
    vector<string> vs{ "a", "b", "a", "b", "e", "f", "a" };
    elimDups(vs);

    return 0;
}

测试:

a a a b b e f
a b e f b a a
a b e f

练习题10.10

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

标准库算法是对迭代器而不是容器进行操作。因此,算法不能(直接)添加或删除元素(P343)。

练习题10.11

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void printWordVec(vector<string>& words){
    for(const auto& word:words )
        cout<<word<<" ";
}
void elimDups(vector<string>& words)
{
    sort(words.begin(), words.end());
    // 按字典序重排words
    auto end_unique = unique(words.begin(), words.end());
    // 重排,使每个单词只出现一次,指向不重复区域之后的迭代器。
    words.erase(end_unique, words.end());
    printWordVec(words);
}
bool isShorter(const string &s1, const string &s2){
    return s1.size() < s2.size();
}
int main()
{
    vector<string> vs{ "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle" };
    printWordVec(vs);
    cout<<"\nuse elimDups: "<<endl;
    elimDups(vs);
    // 使用 isShorter
    sort(vs.begin(), vs.end(), isShorter);
    cout<<"\nuse isShorter: "<<endl;
    printWordVec(vs);

    // 使用 stable_sort
    stable_sort(vs.begin(), vs.end(), isShorter);
    cout<<"\nuse stable_sort: "<<endl;
    printWordVec(vs);
    return 0;
}

测试:

the quick red fox jumps over the slow red turtle
use elimDups:
fox jumps over quick red slow the turtle
use isShorter:
fox red the over slow jumps quick turtle
use stable_sort:
fox red the over slow jumps quick turtle

练习题10.12

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "Sales_data.h"     // Sales_data class.
using namespace std;
inline bool compareIsbn(const Sales_data &sd1, const Sales_data &sd2)
{
    return sd1.isbn().size() < sd2.isbn().size();
}
int main()
{
    Sales_data d1("aa"), d2("aaaa"), d3("aaa"), d4("z"), d5("aaaaz");
    vector<Sales_data> v{ d1, d2, d3, d4, d5 };
   // 迭代器所指向的元素必须与谓词的参数匹配
    sort(v.begin(), v.end(), compareIsbn);
    for(const auto &element : v)
        cout << element.isbn() << " ";
    return 0;
}

练习题10.13

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
bool predicate(const string &s)
{
    return s.size() >= 5;
}
int main()
{
    auto v = vector<string>{ "a", "abc", "aaabbb", "aaabbbc", "aaabbbccc", "aaabbbe" };
    auto pivot = partition(v.begin(), v.end(), predicate);

    for (auto it = v.cbegin(); it != pivot; ++it)
        cout << *it << " ";
    return 0;
}

测试:aaabbbe aaabbbccc aaabbb aaabbbc

练习题10.14

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    auto sum = [](const int a, const int b) { return a+b; };
    cout<<sum(10,5);
    return 0;
}

测试:15

练习题10.15

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
    int a = 10;
    auto sum = [a](const int b) { return a+b; };
    cout<<sum(5);
    return 0;
}

测试:15

练习题10.16

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 来自练习题 10.9
void elimDups(vector<string>& words)
{
    sort(words.begin(), words.end());
    // 按字典序重排words
    auto end_unique = unique(words.begin(), words.end());
    // 重排,使每个单词只出现一次,指向不重复区域之后的迭代器。
    words.erase(end_unique, words.end());

}

void biggies(vector<string> &vs, size_t sz)
{

    elimDups(vs);//将words按字典顺序排序,删除重复单词。

    // 按大小排序,但保持相同大小的字母顺序。
    stable_sort(vs.begin(), vs.end(), [](string const& lhs, string const& rhs){
        return lhs.size() < rhs.size();
    });

    // 获取一个迭代器,指向第一个满足 size() >= sz的元素
    auto wc = find_if(vs.begin(), vs.end(), [sz](string const& s){
            return s.size() >= sz;
    });

    // 打印
    for_each(wc, vs.end(), [](const string &s){
        cout << s << " ";
    });
}

int main()
{
    vector<string> v
    {
        "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"
    };
    cout << "ex10.16: ";
    biggies(v, 4);
    cout << endl;
    return 0;
}

测试:ex10.16: over slow jumps quick turtle

练习题10.17

重新10.12的程序,在对sort的调用中使用lambda来代替函数compareIsbn。

将其中sort一行改为:sort(sale_vec.begin(), sale_vec.end(), [](const Sales_data& sale1, const Sales_data& sale2) { return sale1.isbn().size() > sale2.isbn().size(); });

练习题10.18

重写biggies,用partition代替find_if。我们在10.13中介绍了partition算法。

练习题10.19

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 来自练习题 10.9
void elimDups(vector<string>& words)
{
    sort(words.begin(), words.end());
    // 按字典序重排words
    auto end_unique = unique(words.begin(), words.end());
    // 重排,使每个单词只出现一次,指向不重复区域之后的迭代器。
    words.erase(end_unique, words.end());
}
// ex10.18
void biggies_partition(vector<string> &vs, size_t sz)
{
    elimDups(vs);
    auto pivot = partition(vs.begin(), vs.end(), [sz](const string &s){
        return s.size() >= sz;}
    );
    for(auto it = vs.cbegin(); it != pivot; ++it)
        cout << *it << " ";
}
// ex10.19
void biggies_stable_partition(vector<string> &vs, size_t sz)
{
    elimDups(vs);
    auto pivot = stable_partition(vs.begin(), vs.end(), [sz](const string& s){
        return s.size() >= sz;
    });
    for(auto it = vs.cbegin(); it != pivot; ++it)
        cout << *it << " ";
}
int main()
{
    // 练习题10.18
    vector<string> v{
        "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"
    };
    cout << "ex10.18: ";
    vector<string> v1(v);
    biggies_partition(v1, 4);
    cout << endl;
    // 练习题10.19
    cout << "ex10.19: ";
    vector<string> v2(v);
    biggies_stable_partition(v2, 4);
    cout << endl;
    return 0;
}

测试:

ex10.18: turtle jumps over quick slow
ex10.19: jumps over quick slow turtle

练习题10.20

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

练习题10.21

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 练习题 10.20
size_t bigerThan6(vector<string> const& v)
{
    return count_if(v.cbegin(), v.cend(), [](string const& s){
        return s.size() > 6;
    });
}
int main()
{
    // 10.20
    vector<string> v{
        "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle", "moreThanSix"
    };
    cout << "ex10.20: " << bigerThan6(v) << endl;

    // 练习题10.21
    int i = 6;
    auto check_and_decrement = [&i]() { return i > 0 ? !--i : !i; };//使用&引用
    cout << "ex10.21: ";
    while(!check_and_decrement())
        cout << i << " ";

    return 0;
}

测试:

ex10.20: 1
ex10.21: 5 4 3 2 1

练习题10.22

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
bool isStrShorterThan6(string& str)
{
    return str.size() < 6;
}
int main()
{
    vector<string> v{
        "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle", "moreThanSix"
    };
    int cnt = count_if(v.begin(), v.end(), isStrShorterThan6);
    cout << cnt << endl;
    return 0;
}

测试:9

练习题10.23

bind接受几个参数?

定义:auto newCallable = bind(callable, arg_list);
其中,arg_list是一个用逗号分隔的参数列表,对应给callable的参数。当我们调用newCallable时,实际会调用callable。
arg_list中的参数可能会包含形如_n的名字,其中n是一个整数。这些参数是“占位符”,表示newCallable的参数,它们占据了传递给newCallable的参数位置。

练习题10.24

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

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
bool check_size(string const& str, size_t sz)
{
    return str.size() < sz;
}
int main()
{
    vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7 };
    string str1("12345689");
    string str2("123");
    auto result = find_if(vec.begin(), vec.end(), bind(check_size, str1, std::placeholders::_1));
    if (result != vec.end())
        cout << *result << endl;
    else
        cout << "Not found" << endl;
    result = find_if(vec.begin(), vec.end(), bind(check_size, str2, std::placeholders::_1));
    if (result != vec.end())
        cout << *result << endl;
    else
        cout << "Not found" << endl;
    return 0;
}

测试:

Not found
4

练习题10.25

在10.3.2节的练习中,编写了一个使用partition的biggies版本.使用check_size和bind重写此函数.

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
using namespace std::placeholders;//使用了占位符_1
void printWordVec(vector<string>& words){
    for(const auto& word:words )
        cout<<word<<" ";
    cout<<endl;
}
void elimDups(vector<string>& words)
{
    sort(words.begin(), words.end());
    // 按字典序重排words
    auto end_unique = unique(words.begin(), words.end());
    // 重排,使每个单词只出现一次,指向不重复区域之后的迭代器。
    words.erase(end_unique, words.end());
    printWordVec(words);
}
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);
    auto iter = stable_partition(words.begin(), words.end(), bind(check_size, _1, sz));
    for_each(words.begin(), iter, [](const string &s){ cout << s << " "; });
}

int main()
{
    std::vector<std::string> v{
        "the", "quick", "red", "fox", "jumps", "over", "the", "slow", "red", "turtle"
    };
    biggies(v, 4);
}

测试:

fox jumps over quick red slow the turtle
jumps over quick slow turtle

练习题10.26

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

三种迭代器的区别在于元素插入的位置(P358):

  • back_inserter:创建一个使用push_back的迭代器。
  • front_insert:创建一个使用push_front的迭代器。
  • inserter:创建一个使用insert的迭代器。此函数接受第二个参数,元素将被插入到给定迭代器所表示的元素之前。

练习题10.27

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

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
int main()
{
    vector<string> svec = {"the", "the", "the", "fox", "jumps", "over", "the", "slow", "congratulate", "turtle"};
    list<string> slist(12);//如果不使用插入迭代器需要初始化空间

    unique_copy(svec.begin(), svec.end(), slist.begin());//重复元素必须相邻
    for (auto i : slist) {
        cout << i << " ";
    }
    cout << endl;
    vector<int> vec{ 1, 2, 1, 3, 5, 5, 7, 7, 9 };
    list<int> lst;
    unique_copy(vec.begin(), vec.end(), back_inserter(lst));
    for (auto i : lst)
        cout << i << " ";
    cout << endl;
}

测试:

the fox jumps over the slow congratulate turtle
1 2 1 3 5 7 9

练习题10.28

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

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <list>
#include <iterator>
using namespace std;
void printNum(list<int>& words){
    for(const auto& word:words )
        cout<<word<<" ";
    cout<<endl;
}
int main()
{
    std::vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

    // 使用 inserter
    list<int> lst1;
    copy(vec.cbegin(), vec.cend(), inserter(lst1, lst1.begin()));
    printNum(lst1);

    // 使用 back_inserter
    list<int> lit2;
    copy(vec.cbegin(), vec.cend(), back_inserter(lit2));
    printNum(lit2);

    // 使用 front_inserter
    list<int> lst3;
    copy(vec.cbegin(), vec.cend(), front_inserter(lst3));
    printNum(lst3);
}

测试:

1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11
11 10 9 8 7 6 5 4 3 2 1

练习题10.29

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

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <iterator>
using namespace std;
int main()
{
    ifstream ifs("test.txt");
    istream_iterator<string> in(ifs), eof;
    vector<string> vec;
    copy(in, eof, back_inserter(vec));
    // 输出
    copy(vec.cbegin(), vec.cend(), ostream_iterator<string>(cout, "\n"));
}

测试:

This
is
a
C++
test

练习题10.30

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

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
    istream_iterator<int> in_iter(cin);//输入
    istream_iterator<int> eof;//空
    vector<int> ivec;
    ostream_iterator<int> out_iter(cout, " ");//输出

    while (in_iter != eof) {//当不等于空时
        ivec.push_back(*in_iter++);
    }
    sort(ivec.begin(), ivec.end());
    copy(ivec.begin(), ivec.end(), out_iter);
    cout << endl;
}

测试:

5 2 6 9 1 3
^Z
1 2 3 5 6 9

练习题10.31

修改前一题的程序,使其只打印不重复的元素。你的程序应使用unique_copy。

只需要将上题copy替换:unique_copy(ivec.begin(), ivec.end(), out_iter);

练习题10.32

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

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
#include "Sales_item.h"
using namespace std;
int main()
{
    istream_iterator<Sales_item> in_iter(cin), in_eof;
    vector<Sales_item> vec;

    while (in_iter != in_eof)
        vec.push_back(*in_iter++);
    sort(vec.begin(), vec.end(), compareIsbn);
    for (auto beg = vec.cbegin(), end = beg; beg != vec.cend(); beg = end) {
        end = find_if(beg, vec.cend(), [beg](const Sales_item &item){ return item.isbn() != beg->isbn(); });
        cout << accumulate(beg, end, Sales_item(beg->isbn())) << endl;
    }
}

练习题10.33

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

#include <fstream>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
    ifstream ifs("input.txt");
    ofstream ofs_odd("odd.txt"), ofs_even("even.txt");

    istream_iterator<int> in(ifs), in_eof;
    ostream_iterator<int> out_odd(ofs_odd, " "), out_even(ofs_even, " ");

    for_each(in, in_eof, [&out_odd, &out_even](const int i){
        *(i & 0x1 ? out_odd : out_even)++ = i;//奇偶判断
    });

    return 0;
}

在这里插入图片描述

练习题10.34

使用reverse_iterator逆序打印一个vector。

练习题10.35

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

练习题10.36

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

练习题10.37

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

#include <iostream>
#include <algorithm>
#include <list>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
    vector<int> vec = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    // 练习题10.34
    cout<<"ex10.34: ";
    for (auto rit = vec.crbegin(); rit != vec.crend(); ++rit)
        cout << *rit << " ";
    cout << endl;
    // 练习题10.35
    cout<<"ex10.35: ";
    for (auto it = prev(vec.cend()); true; --it) {
        cout << *it << " ";
        if (it == vec.cbegin()) break;
    }
    cout << endl;
    // 练习题10.36
    cout<<"ex10.36: ";
    list<int> lst = { 1, 2, 3, 4, 0, 5, 6 };
    auto found_0 = find(lst.crbegin(), lst.crend(), 0);
    cout << distance(found_0, lst.crend()) << endl;
    // 练习题10.37
    list<int> ret_lst(8 - 3);
    copy(vec.cbegin() + 3, vec.cbegin() + 8, ret_lst.rbegin());
    //     0, 1, 2, 3, 4, 5, 6, 7, 8, 9
    //           ^              ^
    //          rend          rbegin
    // @note: copy将范围[first, last]复制到结果中。
    //        因此,这里的参数表示:
    //        [7 6 5 4 3 2)
    //                   ^ 这只是指定,但不包括。
    cout<<"ex10.37: ";
    for (auto i : ret_lst) cout << i << " ";
    cout << endl;
}

测试:

ex10.34: 9 8 7 6 5 4 3 2 1 0
ex10.35: 9 8 7 6 5 4 3 2 1 0
ex10.36: 5
ex10.37: 7 6 5 4 3

练习题10.38

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

P366

  • 输入迭代器:只读,不写;单遍扫描,只能递增。支持==、!=、++、*、->
  • 输出迭代器:只写,不读;单遍扫描,只能递增。支持++、*
  • 前向迭代器:可读写,多边扫描,只能递增。支持输入输出迭代器的所有操作。
  • 双向迭代器:可读写,多遍扫描,可递增递减。除支持前向迭代器的操作外,还支持–。
  • 随机访问迭代器:可读写,多遍扫描,支持全部迭代器运算。除支持双向操作外,还支持<、<=、>、>=、+、+=、-、-=、迭代器的减法运算符(-)、下标运算符(iter[n], *(iter[n]) )。

练习题10.39

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

  • list的迭代器属于双向迭代器。
  • vector属于随机访问迭代器。

练习题10.40

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

  • copy前两个参数要求输入迭代器,最后一个参数要求输出迭代器。

  • reverse要求双向迭代器。

  • unique要求前向迭代器。

练习题10.41

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

(a)replace(beg, end, old_val, new_val);
替换操作,从beg到end,把old_val替换成new_val
(b)replace_if(beg, end, pred, new_val);
替换操作,从beg到end,如果满足pred条件,就把old_val替换成new_val
(c)replace_copy(beg, end, dest, old_val, new_val);
替换拷贝操作,从beg到end,把old_val替换成new_val,并拷贝至dest
(d)replace_copy_if(beg, end, dest, pred, new_val);
替换拷贝操作,从beg到end,如果满足pred条件,就把old_val替换成new_val,并拷贝至dest

练习题10.42

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

#include <iostream>
#include <string>
#include <list>
using namespace std;
void elimDups(list<string> &words)
{
    words.sort();
    words.unique();
    for(const auto word : words)
        cout<<word<<" ";
}
int main()
{
    list<string> l = { "aa", "bb", "cc", "aa", "aasss", "aa", "cc" };
    elimDups(l);
}

测试:aa aasss bb cc

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值