C++primer(第5版)第十章泛型算法习题答案

10.1 && 10.2

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

int main()
{
    // 10.1
    std::vector<int> v = {1, 2, 3, 4, 5, 6, 6, 6, 2};
    std::cout << "ex 10.01: " << std::count(v.cbegin(), v.cend(), 6)
              << std::endl;

    // 10.2
    std::list<std::string> l = {"aa", "aaa", "aa", "cc"};
    std::cout << "ex 10.02: " << std::count(l.cbegin(), l.cend(), "aa")
              << std::endl;

    return 0;
}

10.3 && 10.4

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

int main()
{
    // 10.3
    std::vector<int> v = {1, 2, 3, 4};
    std::cout << "ex 10.03: " << std::accumulate(v.cbegin(), v.cend(), 0)
              << std::endl;

    // 10.4
    std::vector<double> vd = {1.1, 0.5, 3.3};
    std::cout << "ex 10.04: " << std::accumulate(vd.cbegin(), vd.cend(), 0)
              << std::endl; 
    return 0;

// 输出为4,而不是预期的4.9
}

10.5

在两个c样式字符串容器之间进行比较时,函数“equal”可能返回true。 尽管如此,我们需要记住,当涉及到c样式字符串的比较时,我们需要使用“strcmp”,而不仅仅是关系运算符,因为使用关系运算符只是两个c样式字符串地址之间的比较,而不是它们的值。

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

int main()
{
    char c1[10] = "eipi10";
    char c2[10] = "eipi10";
    std::vector<char*> roster1{c1};
    std::list<char*> roster2{c2};
    std::cout << std::equal(roster1.cbegin(), roster1.cend(), roster2.cbegin());
    return 0;
}

10.6

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

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

int main()
{
    vector<int> vec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    fill_n(vec.begin(), vec.size(), 0);

    for (auto i : vec) cout << i << " ";
    cout << endl;
}

10.7

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

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

template <typename Sequence> void print(Sequence const& seq)
{
    for (const auto& i : seq) cout << i << " ";
    cout << endl;
}

int main()
{
    vector<int> vec;
    list<int> lst;
    int i;
    while (cin >> i) lst.push_back(i);
    vec.resize(lst.size());
    copy(lst.cbegin(), lst.cend(), vec.begin());
    vector<int> v;
    v.reserve(10);
    fill_n(v.begin(), 10, 0);
    print(v);
    print(vec);
}

10.8

因为back_inserter是一个插入迭代器,即生成迭代器的迭代器适配器,该迭代器使用容器操作将元素添加到给定的容器中。算法不会改变大小,但迭代器可以通过使用容器操作来改变大小。

10.9

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

template <typename Sequence> auto println(Sequence const& seq) -> std::ostream &
{
    for (auto const& elem : seq) std::cout << elem << " ";
    return std::cout << std::endl;
}

auto eliminate_duplicates(std::vector<std::string>& vs)
    -> std::vector<std::string> &
{
    std::sort(vs.begin(), vs.end());
    println(vs);

    auto new_end = std::unique(vs.begin(), vs.end());
    println(vs);

    vs.erase(new_end, vs.end());
    return vs;
}

int main()
{
    std::vector<std::string> vs{"a", "v", "a", "s", "v", "a", "a"};
    println(vs);
    println(eliminate_duplicates(vs));

    return 0;
}

10.10

这个设计的目的是将算法和成员函数提供的操作分开。因为库算法操作迭代器,而不是容器。因此,算法不能(直接)添加或删除元素。

10.11

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

template <typename Sequence> inline std::ostream& println(Sequence const& seq)
{
    for (auto const& elem : seq) std::cout << elem << " ";
    std::cout << std::endl;

    return std::cout;
}

inline bool is_shorter(std::string const& lhs, std::string const& rhs)
{
    return lhs.size() < rhs.size();
}

void elimdups(std::vector<std::string>& vs)
{
    std::sort(vs.begin(), vs.end());
    auto new_end = std::unique(vs.begin(), vs.end());
    vs.erase(new_end, vs.end());
}

int main()
{
    std::vector<std::string> v{"1234", "1234", "1234", "Hi", "alan", "wang"};
    elimdups(v);
    std::stable_sort(v.begin(), v.end(), is_shorter);
    std::cout << "ex10.11 :\n";
    println(v);

    return 0;
}

10.12

#include <algorithm>
#include <numeric>
#include <vector>

#include "../ch07/ex7_26_sales_data.h" // Sales_data class.

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

int main()
{
    Sales_data d1("CppPrimer"), d2("JavaCore"), d3("PythonCookBook"),
        d4("CppCore"), d5("AwesomeCPP");
    std::vector<Sales_data> v{d1, d2, d3, d4, d5};
    std::sort(v.begin(), v.end(), compareIsbn);

    for (const auto& element : v) std::cout << element.isbn() << " ";
    std::cout << std::endl;
}


10.13

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

bool predicate(const std::string& s)
{
    return s.size() >= 5;
}

int main()
{
    auto v = std::vector<std::string>{"a",         "as",        "aasss",
                                      "aaaaassaa", "aaaaaabba", "aaa"};
    auto pivot = std::partition(v.begin(), v.end(), predicate);

    for (auto it = v.cbegin(); it != pivot; ++it) std::cout << *it << " ";
    std::cout << std::endl;

    return 0;
}

10.14

auto add = [](int lhs, int rhs){return lhs + rhs;};

10.15

int i = 42;
auto add = [i](int num){return i + num;};

10.16

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

void elimdups(std::vector<std::string>& vs)
{
    std::sort(vs.begin(), vs.end());
    auto new_end = std::unique(vs.begin(), vs.end());
    vs.erase(new_end, vs.end());
}

void biggies(std::vector<std::string>& vs, std::size_t sz)
{
    using std::string;

    elimdups(vs);

    std::stable_sort(vs.begin(), vs.end(),
                     [](string const& lhs, string const& rhs) {
                         return lhs.size() < rhs.size();
                     });

    auto wc = std::find_if(vs.begin(), vs.end(),
                           [sz](string const& s) { return s.size() >= sz; });

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

int main()
{
    std::vector<std::string> v{"1234", "1234", "1234", "hi~",
                               "alan", "alan", "cp"};
    std::cout << "ex10.16: ";
    biggies(v, 3);
    std::cout << std::endl;

    return 0;
}

10.17

#include <algorithm>
#include <vector>

#include "../ch07/ex7_26_sales_data.h" // Sales_data class.

int main()
{
    Sales_data d1("CppPrimer"), d2("JavaCore"), d3("PythonCookBook"),
        d4("CppCore"), d5("AwesomeCPP");
    std::vector<Sales_data> v{d1, d2, d3, d4, d5};

    std::sort(v.begin(), v.end(),
              [](const Sales_data& sd1, const Sales_data& sd2) {
                  return sd1.isbn() < sd2.isbn();
              });

    for (const auto& element : v) std::cout << element.isbn() << " ";
    std::cout << std::endl;
}

10.18 && 10.19

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


void elimdups(std::vector<std::string>& vs)
{
    std::sort(vs.begin(), vs.end());
    auto new_end = std::unique(vs.begin(), vs.end());
    vs.erase(new_end, vs.end());
}

//10.18
void biggies_partition(std::vector<std::string>& vs, std::size_t sz)
{
    elimdups(vs);

    auto pivot = partition(vs.begin(), vs.end(), [sz](const std::string& s) {
        return s.size() >= sz;
    });

    for (auto it = vs.cbegin(); it != pivot; ++it) std::cout << *it << " ";
}

//10.19
void biggies_stable_partition(std::vector<std::string>& vs, std::size_t sz)
{
    elimdups(vs);

    auto pivot =
        stable_partition(vs.begin(), vs.end(),
                         [sz](const std::string& s) { return s.size() >= sz; });

    for (auto it = vs.cbegin(); it != pivot; ++it) std::cout << *it << " ";
}

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

    std::cout << "ex10.18: ";
    std::vector<std::string> v1(v);
    biggies_partition(v1, 4);
    std::cout << std::endl;

    //10.19
    std::cout << "ex10.19: ";
    std::vector<std::string> v2(v);
    biggies_stable_partition(v2, 4);
    std::cout << std::endl;

    return 0;
}

10.20

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

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

int main()
{
    vector<string> words{"cppprimer", "pezy",    "learncpp",
                         "greater",   "rewrite", "programmer"};

    cout << std::count_if(words.cbegin(), words.cend(), [](const string& word) {
        return word.size() > 6;
    }) << std::endl;
}

10.21

#include <iostream>

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

int main()
{
    // local int variable
    int local_val = 7;
    auto decrement_to_zero = [&local_val]() {
        if (local_val == 0)
            return true;
        else {
            --local_val;
            return false;
        }
    };

    while (!decrement_to_zero()) cout << local_val << endl;
}

10.22

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


using std::string;
using namespace std::placeholders;

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

int main()
{
    std::vector<string> authors{"Mooophy", "pezy", "Queequeg90", "shbling",
                                "evan617"};
    std::cout << count_if(authors.cbegin(), authors.cend(),
                          bind(lessThanOrEqualTo, _1, 6));
}

10.23

假设要绑定的函数有n个参数,则绑定取n+1个参数。另一个是函数自身绑定。

10.24

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

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

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

inline vector<int>::const_iterator find_first_bigger(const vector<int>& v,
                                                     const string& s)
{
    return find_if(v.cbegin(), v.cend(),
                   bind(check_size, s, std::placeholders::_1));
}

int main()
{
    vector<int> v{1, 2, 3, 4, 5, 6, 7};
    string s("test");
    cout << *find_first_bigger(v, s) << endl;

    return 0;
}

10.25

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

using std::string;
using std::vector;
using namespace std::placeholders;

void elimdups(vector<string>& vs)
{
    std::sort(vs.begin(), vs.end());
    vs.erase(unique(vs.begin(), vs.end()), vs.end());
}

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 = std::stable_partition(words.begin(), words.end(),
                                      bind(check_size, _1, sz));
    for_each(words.begin(), iter,
             [](const string& s) { std::cout << s << " "; });
}

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

10.26

back_inserter使用push_back。
front_inserter使用push_front。
insert使用insert>此函数接受第二个参数,该参数必须是给定容器的迭代器。元素插入在给定迭代器表示的元素之前。

10.27

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

int main()
{
    std::vector<int> vec{3, 5, 1, 5, 1, 7, 3, 7, 9};
    std::list<int> lst;

    std::sort(vec.begin(), vec.end());
    std::unique_copy(vec.begin(), vec.end(), back_inserter(lst));
    for (auto i : lst) std::cout << i << " ";
    std::cout << std::endl;
}

10.28

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

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

template <typename Sequence> void print(Sequence const& seq)
{
    for (const auto& i : seq) std::cout << i << " ";
    std::cout << std::endl;
}

int main()
{
    std::vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9};

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

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

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

10.29

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

using std::string;

int main()
{
    std::ifstream ifs("../data/book.txt");
    std::istream_iterator<string> in(ifs), eof;
    std::vector<string> vec;
    std::copy(in, eof, back_inserter(vec));

    // output
    std::copy(vec.cbegin(), vec.cend(),
              std::ostream_iterator<string>(std::cout, "\n"));
}

10.30

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

int main()
{
    std::istream_iterator<int> in_iter(std::cin), eof;
    std::vector<int> vec;
    while (in_iter != eof) vec.push_back(*in_iter++);
    std::sort(vec.begin(), vec.end());
    std::copy(vec.cbegin(), vec.cend(),
              std::ostream_iterator<int>(std::cout, " "));
}

10.31

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

int main()
{
    std::istream_iterator<int> in_iter(std::cin), eof;
    std::vector<int> vec;
    while (in_iter != eof) vec.push_back(*in_iter++);
    std::sort(vec.begin(), vec.end());
    std::unique_copy(vec.cbegin(), vec.cend(),
                     std::ostream_iterator<int>(std::cout, " "));
}

10.32

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

int main()
{
    std::istream_iterator<Sales_item> in_iter(std::cin), in_eof;
    std::vector<Sales_item> vec;

    while (in_iter != in_eof) vec.push_back(*in_iter++);
    sort(vec.begin(), vec.end(),
         [](Sales_item const& lhs, Sales_item const& rhs) {
             return lhs.isbn() < rhs.isbn();
         });
    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();
        });
        std::cout << std::accumulate(beg, end, Sales_item(beg->isbn()))
                  << std::endl;
    }
}

10.33

#include <fstream>
#include <iterator>
#include <algorithm>

int main(int argc, char** argv)
{
    if (argc != 4) return -1;

    std::ifstream ifs(argv[1]);
    std::ofstream ofs_odd(argv[2]), ofs_even(argv[3]);

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

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

    return 0;
}

10.34 - 10.37

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

int main()
{
    std::vector<int> v = {4, 5, 7, 9, 6, 3, 1, 0, 2, 3};

    //! 10.34
    for (auto iter = v.crbegin(); iter != v.crend(); ++iter)
        std::cout << *iter << " ";
    std::cout << std::endl;

    //! 10.35
    for (auto iter = v.cend(); iter != v.cbegin();)
        std::cout << *--iter << " ";
    std::cout << std::endl;

    //! 10.36
    std::list<int> l = {3, 7, 0, 3, 4, 0, 5};
    auto found = std::find(l.crbegin(), l.crend(), 0);
    std::cout << *found << " in front of " << *found.base() << std::endl;

    //! 10.37
    std::list<int> ret_l(7 - 3 + 1);
    std::reverse_copy(v.cbegin() + 3, v.cbegin() + 8, ret_l.begin());
    for (auto i : ret_l)
        std::cout << i << " ";
    std::cout << std::endl;
}

10.38

 输入迭代器:==,!=,++
 输出迭代器:++ 
 正向迭代器:==,!=,++,->   
 双向迭代器:==,!=,++,--,->   
 随机访问迭代器:==,!=,<,<=,>,>=,++,--,+,+=,-,

10.39

list具有双向迭代器。vector具有随机访问迭代器。

10.40

copy:第一个和第二个是输入迭代器,最后一个是输出迭代器。
reverse:双向迭代器。
unique:转发迭代器。

10.41

replace(beg, end, old_val, new_val); // replace the old_elements in the input range as new_elements.
replace_if(beg, end, pred, new_val); // replace the elements in the input range which pred is true as new_elements.
replace_copy(beg, end, dest, old_val, new_val); // copy the new_elements which is old_elements in the input range into dest.
replace_copy_if(beg, end, dest, pred, new_val); // copy the new_elements which pred is true in the input range into dest.

10.42

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

using std::string;
using std::list;

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

int main()
{
    list<string> l = {"aa", "aa", "aa", "aa", "aasss", "aa"};
    elimDups(l);
    for (const auto& e : l) std::cout << e << " ";
    std::cout << std::endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值