• cppPrimer学习-10th



    title: cppPrimer学习10th
    date: 2020/1/6 19:35:42
    toc: true

    cppPrimer学习10th

    备忘

    • 只读算法
    find
    count
    accumulate //求和
    equal
    
    • 写容器算法
    fill
    fill_n  fill_n(v.begin(), v.size(), 0);
    // back_inserter(containter) 返回一个插入的迭代器,对他赋值执行push_back
    copy
    sort
    unique
    stable_sort
    
    
    
    • 谓词 P344

      mark

    • equal 比较的是==,对于char*的类型实际比较的是char*也就是地址,而对于string来说,有重载==操作符

    • unique删除重复之前需要排序,它只是删除相邻相同的元素

    • 迭代器类别

      输入迭代器:只读,不写;单遍扫描,只能递增。支持==、!=、++、*、->
      输出迭代器:只写,不读;单遍扫描,只能递增。支持++、*
      前向迭代器:可读写,多边扫描,只能递增。支持输入输出迭代器的所有操作。
      双向迭代器:可读写,多遍扫描,可递增递减。除支持前向迭代器的操作外,还支持--。
      随机访问迭代器:可读写,多遍扫描,支持全部迭代器运算。除支持双向操作外,还支持<、<=、>、>=、+、+=、-、-=、迭代器的减法运算符(-)、下标运算符(iter[n], *(iter[n]) )。
      
    • 对于listforward_list,应该使用容器定义的成员函数的算法,因为一方面链表可以直接修改链接达到交换元素的目的,另一方面比如sort需要支持随机访问而链表不支持等 p369

    10.1

    /*
    头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数。count返回给定值在序列中出现的次数。
    编写程序,读取int序列存入vector中,打印有多少个元素的值等于给定值
    */
    #include "algorithm"
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        vector<int> v = {1, 2, 3, 4, 5, 6, 3, 8, 9, 3, 5, 5};
        auto findme = count(v.begin(), v.end(), 3);
        cout << findme << endl;
        while (1)
            ;
        return 0;
    }
    

    10.2

    /*
    头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数。count返回给定值在序列中出现的次数。
    编写程序,读取string序列存入list中,打印有多少个元素的值等于给定值
    */
    
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
    
        list<string> l = {"123", "456", "111", "123", "456", "123"};
    
        auto has = count(l.begin(), l.end(), "123");
        cout << "123 has " << has << endl;
    
        while (1)
            ;
        return 0;
    }
    

    10.3

    10.4

    /*用accumulate求一个vector中的元素之和*/
    /*假定v是一个vector, 那么调用accumulate(v.cbegin(), v.cend(), 0)有何错误(如果存在)
    	返回的是int
    */
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8};
    
        auto sum = accumulate(v.begin(), v.end(), 0);
        cout << sum << endl;
    
        vector<double> v2 = {1.1, 1.2};
        auto sum2 = accumulate(v2.begin(), v2.end(), (double)0); //或者0.0都可以
        cout << sum2 << endl;
    
        while (1)
            ;
        return 0;
    }
    

    10.5

    /*
    在本节对名册(roster)调用equal的例子中,如果两个名册中保存的都是c风格字符串而不是string,会发生什么?
    
    答案: 比较的是迭代器指的地址在使用char* 的类型
    
    equal使用==运算符比较两个序列中的元素。string类重载了==,可比较两个字符串是否长度相等且其中元素对位相等。
    而C风格字符串本质是char *类型,用==比较两个char *对象,只是检查两个指针值是否相等,即地址是否相等,而不会比较其中字符是否相同。
    所以,只有当两个序列中的指针都指向相同的地址时,equal才会返回true,否则,即使字符串内容完全相同,也会返回false。
    
    原文链接:https://blog.csdn.net/sunhero2010/article/details/49803965
    
    
    For such case, std::equal is going to compare the address value rather than the string value.
     So the result is not the same as std::string. Try to avoid coding this way.
    */
    
    #include "include.h"
    
    void printAddr(const char *addr)
    {
        unsigned int a;
    
        for (int i = 0; i < 6; i++)
        {
            a = (*(addr + i)) & 0xff;
            cout << a << "  ";
        }
        cout << endl;
    }
    
    int main(int argc, char const *argv[])
    {
        // const char *s1 = "123456789";
        // const char *s2 = "123456789111111";
        // auto ret = equal(begin(s1), end(s1), begin(s2));
        // cout << ret << endl;
    
        std::vector<const char *> roster1{"Mooophy", "pezy", "Queequeg"};
        std::list<const char *> roster2{"Mooophy", "pezy", "Queequeg", "shbling", "evan617"};
        std::cout << boolalpha << std::equal(roster1.cbegin(), roster1.cend(), roster2.cbegin()) << endl;
    
        const char a[3][2] = {"A", "B", "C"};
        const char b[3][2] = {"A", "B", "C"};
    
        std::vector<const char *> v1(std::begin(a), std::end(a));
        std::list<const char *> v2(std::begin(b), std::end(b));
    
        cout << "a=" << begin(a) << "----" << end(a) << endl;
        printAddr((const char *)&(*begin(a)));
        cout << "b=" << begin(b) << "----" << end(b) << endl;
        printAddr((const char *)&(*begin(b)));
    
        std::cout << std::boolalpha
                  << std::equal(v1.cbegin(), v1.cend(), v2.cbegin()) << std::endl;
    
        cout << "v1_address=" << &*v1.begin() << "----" << &*v1.end() << endl;
        cout << "v2_address=" << &*v2.begin() << "----" << &*v2.end() << endl;
        printAddr((const char *)&(*v1.begin()));
        printAddr((const char *)&(*v2.begin()));
    
        vector<string> v3{"A", "B", "C"};
        vector<string> v4{"A", "B", "C"};
    
        cout << "v3_address=" << &*v3.begin() << "----" << &*v3.end() << endl;
        cout << "v4_address=" << &*v4.begin() << "----" << &*v4.end() << endl;
        printAddr((const char *)&(*v3.begin()));
        printAddr((const char *)&(*v4.begin()));
        std::cout << std::boolalpha
                  << std::equal(v3.cbegin(), v3.cend(), v4.cbegin()) << std::endl;
    
        while (1)
            ;
        return 0;
    }
    
    

    10.6

    /*
    编写程序,使用fill_n将一个序列中的int都设置为0
    */
    
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
    
        vector<int> v = {1, 2, 3, 4, 5, 6, 7};
    
        fill_n(v.begin(), v.size(), 0);
        print(v);
        while (1)
            ;
        return 0;
    }
    

    10.7

    /*
    下面程序是否有错误?如果有,请改正。
    reserve 只是确保当前size<capacity,扩充容量但是不会改变size
    */
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        vector<int> vec;
        list<int> lst;
        int i;
        while (cin >> i)
            lst.push_back(i);
    
        //-------------------
        vec.reserve(lst.size()); // 虽然不会报错误,但是不会有打印的
        //vec.resize(lst.size());
        copy(lst.cbegin(), lst.cend(), vec.begin());
        print(vec);
    
        while (1)
            ;
    
        return 0;
    }
    

    10.8

    标准库算法不会改变他们所操作的容器的大小。为什么使用back_inserter不会使这一断言失效
    
    标准库算法根本不知道有“容器”这个东西。它们只接受迭代器参数,运行于这些迭代器之上,通过这些迭代器来访问元素。
    back_inserter 的迭代器能调用对应的插入算法
    
    

    10.9

    /*
    实现你自己的elimDups。测试你的程序,分别在读取输入后、调用unique后以及调用erase后打印vector的内容
    */
    
    #include "include.h"
    
    void elimDups(vector<string> &s)
    {
        print(s);
        sort(s.begin(), s.end());
        print(s);
        auto last = unique(s.begin(), s.end());
        print(s);
        s.erase(last, s.end());
        print(s);
    }
    
    int main(int argc, char const *argv[])
    {
        vector<string> vs = {"999",
                             "123",
                             "456",
                             "123",
                             "777",
                             "999"};
    
        elimDups(vs);
        while (1)
            ;
        return 0;
    }
    

    10.10

    你认为算法不改变容器大小的原因是什么?
    
    泛型算法为了实现通用化,识别的是迭代器,改变容器大小会使迭代器失效,泛型算法原则上也不知道容器的存在
    

    10.11

    /*
    编写程序,使用 stable_sort 和isShorter将传递给你的elimDups版本的vector排序。打印vector的内容,验证你的程序的正确性。
    */
    
    #include "include.h"
    
    bool isShorter(const string &a, const string &b)
    {
        return a.size() < b.size();
    }
    
    void elimDups(vector<string> &s)
    {
        print(s);
        sort(s.begin(), s.end());
        print(s);
        auto last = unique(s.begin(), s.end());
        print(s);
        s.erase(last, s.end());
        print(s);
    
        stable_sort(s.begin(), s.end(), isShorter);
        print(s);
    }
    
    int main(int argc, char const *argv[])
    {
        vector<string> vs = {"9990000",
                             "123000000000",
                             "456",
                             "123000000000",
                             "777",
                             "9990000"};
    
        elimDups(vs);
        while (1)
            ;
        return 0;
    }
    
    

    10.12

    //编写名为compareIsbn的函数,比较两个Sales_data对象的isbn()成员。使用这个函数排序一个保存Sales_data对象的vector。
    
    #include "Sales_data.h"
    #include "include.h"
    
    bool compareIsbn(const Sales_data &a, const Sales_data &b)
    {
        return a.isbn() < b.isbn();
    }
    
    int main(int argc, char const *argv[])
    {
        Sales_data a("999");
        Sales_data b("456");
        Sales_data c("222");
    
        vector<Sales_data> v = {a, b, c};
        sort(v.begin(), v.end(), compareIsbn);
        for (auto ch : v)
        {
            cout << ch.isbn() << endl;
        }
    
        while (1)
            ;
        return 0;
    }
    
    

    10.13

    
    /*
    标准库定义了名为partition的算法,它接受一个谓词,对容器内容进行划分,使得谓词为true的值对排在容器的前半部分,而使谓词为false的值会排在后半部分。
    算法返回一个迭代器,指向最后一个使谓词为true的元素之后的位置。编写函数,接受一个string,返回一个bool值,指出string是否有5个或更多字符。
    使用此函数划分words。打印出长度大于等于5的元素
    */
    #include "include.h"
    
    bool bigThen5(const string &a)
    {
        return a.size() > 5;
    }
    
    int main(int argc, char const *argv[])
    {
        vector<string> v = {"123456",
                            "12345",
                            "111222",
                            "55555555"};
    
        auto last_true = partition(v.begin(), v.end(), bigThen5);
    
        for (auto i = v.begin(); i != last_true; i++)
        {
            cout << *i << endl;
        }
    
        while (1)
            ;
        return 0;
    }
    
    

    10.14

    /*
    lamdda 接收两个int 返回sum
    */
    
    #include "include.h"
    int main(int argc, char const *argv[])
    {
    
        auto f = [](const int a, const int b) { return a + b; };
    
        cout << f(1, 2) << endl;
    
        while (1)
            ;
        return 0;
    }
    

    10.15

    /*
    编写一个lambda,捕获它所在函数的int,并接受一个int参数。lambda应该返回捕获的int和int参数的和
    */
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        int a = 1;
        auto f = [a](int b) { return a + b; };
        cout << f(3) << endl;
        while (1)
            ;
        return 0;
    }
    

    10.16

    /*
    求一个大于等于给定长度的单词有多少,并将其打印出来
    void biggiest(vector<string>v,vector<string>::size_type sz)
    */
    #include "include.h"
    
    void biggiest(vector<string> v, vector<string>::size_type sz)
    {
        // 按照字典排序,删除重复单词
        sort(v.begin(), v.end());
        auto last = unique(v.begin(), v.end());
        v.erase(last, v.end());
    
        // 按照长度排序,这里需要传递一个长度 使用lamada
        stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
    
        //找到第一个长度>sz的迭代器
        auto fst = find_if(v.begin(), v.end(), [sz](const string &a) { return a.size() >= sz; });
    
        // 打印vec
        for_each(fst, v.end(), [](const string &a) { cout << a << endl; });
    }
    
    int main(int argc, char const *argv[])
    {
        vector<string> v = {"0", "123", "1234", "hello", "world", "99999999999", "world"};
        biggiest(v, 4);
    
        while (1)
            ;
        return 0;
    }
    
    

    10.17

    //重新10.12的程序,在对sort的调用中使用lambda来代替函数compareIsbn
    
    #include "Sales_data.h"
    #include "include.h"
    
    bool compareIsbn(const Sales_data &a, const Sales_data &b)
    {
        return a.isbn() < b.isbn();
    }
    
    int main(int argc, char const *argv[])
    {
        Sales_data a("999");
        Sales_data b("456");
        Sales_data c("222");
    
        vector<Sales_data> v = {a, b, c};
        vector<Sales_data> v2(v);
        sort(v.begin(), v.end(), compareIsbn);
    
        for (auto ch : v)
        {
            cout << ch.isbn() << endl;
        }
    
        sort(v2.begin(), v2.end(), [](const Sales_data &a, const Sales_data &b) { return a.isbn() < b.isbn(); });
        for (auto ch : v2)
        {
            cout << ch.isbn() << endl;
        }
    
        while (1)
            ;
        return 0;
    }
    
    

    10.18

    10.19

    /*
    求一个大于等于给定长度的单词有多少,并将其打印出来
    void biggiest(vector<string>v,vector<string>::size_type sz)
    
    
    -------------------------------sort by dic
    0,123,1234,99999999999,hello,world,
    -------------------------------sort by dic,then stable_sort by len,then use findif
    1234,hello,world,99999999999,
    -------------------------------sort by dic,then partition
    world,hello,1234,99999999999,
    -------------------------------sort by dic,then stable_partition
    1234,99999999999,hello,world,
    
    
    */
    #include "include.h"
    
    string make_plural(size_t ctr, const string &word, const string &ending)
    {
        return (ctr > 1) ? word + ending : word;
    }
    void elimdups(vector<string> &words)
    {
        sort(words.begin(), words.end());
        auto end_unique = unique(words.begin(), words.end());
        words.erase(end_unique, words.end());
    }
    
    void biggiest2(vector<string> &words, vector<string>::size_type sz)
    {
        elimdups(words); //将words按字典序排序,删除重复词
    
        // 获取一个迭代器,指向最后一个满足size()>=sz的元素之后的位置
        auto wc = partition(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });
        // 计算满足size()>=sz的元素的数目
        auto count = wc - words.begin();
        cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
        // 打印长度大于等于给定值的单词,每个单词后面接一个空格
        for_each(words.begin(), wc, [](const string &s) { cout << s << " "; });
        cout << endl;
    }
    
    void biggiest(vector<string> v, vector<string>::size_type sz)
    {
        // 按照字典排序,删除重复单词
        sort(v.begin(), v.end());
        auto last = unique(v.begin(), v.end());
        v.erase(last, v.end());
    
        vector<string> cp1(v);
        vector<string> cp2(v);
    
        cout << "-------------------------------sort by dic" << endl;
        for_each(cp1.begin(), cp1.end(), [](const string &a) { cout << a << ","; });
        cout << endl;
    
        cout << "-------------------------------sort by dic,then stable_sort by len,then use findif" << endl;
        // 按照长度排序,这里需要传递一个长度 使用lamada
        stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
        //找到第一个长度>sz的迭代器
        auto fst = find_if(v.begin(), v.end(), [sz](const string &a) { return a.size() >= sz; });
        // 打印vec
        for_each(fst, v.end(), [](const string &a) { cout << a << ","; });
        cout << endl;
    
        cout << "-------------------------------sort by dic,then partition" << endl;
        auto lst = partition(cp1.begin(), cp1.end(), [sz](const string &a) { return a.size() >= sz; });
        for_each(cp1.begin(), lst, [](const string &a) { cout << a << ","; });
        cout << endl;
    
        cout << "-------------------------------sort by dic,then stable_partition" << endl;
        auto lst2 = stable_partition(cp2.begin(), cp2.end(), [sz](const string &a) { return a.size() >= sz; });
        for_each(cp2.begin(), lst2, [](const string &a) { cout << a << ","; });
        cout << endl;
    }
    
    int main(int argc, char const *argv[])
    {
        vector<string> v = {"0", "123", "1234", "hello", "world", "99999999999", "world"};
        biggiest(v, 4);
    
        while (1)
            ;
        return 0;
    }
    
    

    10.20

    /*
    标准库定义了一个名为count_if的算法。类似find_if,此函数接受一对迭代器,表示一个输入范围,还接受一个谓词,会对输入范围中每个元素执行。
    count_if返回一个计数值,表示谓词有多少次为真。使用count_if重写我们程序中统计有多少单词长度超过6的部分。
    */
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        vector<string> v = {"123", "1233", "ssss", "123456789", "123564789"};
    
        auto cnt = count_if(v.begin(), v.end(), [](const string &a) { return a.size() > 6; });
        cout << cnt << endl;
        while (1)
            ;
        return 0;
    }
    

    10.21

    /*
    编写一个lambda,捕获一个局部int变量,并递减变量值,直至它变为0.一旦变为0,再调用lambda应该不再递减变量。lambda应该返回一个bool值,指出捕获的变量是否为0.
    */
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        int z = 3;
    
        //auto f = [&z]() {if(z)z--; return(z?false:true); };
        // 也可以使用尾置返回
        auto f = [&z]() -> int {if(z)z--; return(z?false:true); };
    
        while (z)
        {
            f();
            cout << z << endl;
        }
        while (1)
            ;
        return 0;
    }
    
    

    10.22

    /*
    重写统计长度小于等于6的单词数量的程序,使用函数代替lambda.
    */
    #include "include.h"
    #include <functional>
    using namespace std::placeholders;
    bool cnt(const string &a, string::size_type sz)
    {
        return a.size() <= sz;
    }
    
    int main(int argc, char const *argv[])
    {
    
        vector<string> v = {"123", "1233", "ssss", "123456789", "123564789"};
    
        //auto f = bind(cnt, _1, 6);
        //auto cnt = count_if(v.begin(), v.end(), f);
    
        auto cnt = count_if(v.begin(), v.end(), bind(cnt, _1, 6));
        cout << cnt << endl;
        while (1)
            ;
        return 0;
        while (1)
            ;
        return 0;
    }
    
    

    10.23

    bind接受几个参数
    第一个参数是函数,后面的参数实际就是函数的参数,
    

    10.24

    #include "include.h"
    
    bool check(int a, int sz)
    {
        return a > sz;
    }
    
    int main(int argc, char const *argv[])
    {
        vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
        string s = "123";
        auto f = bind(check, _1, s.size());
    
        auto fst = find_if(v.begin(), v.end(), f);
    
        cout << *fst << endl;
    
        while (1)
            ;
        return 0;
    }
    
    

    10.25

    /*
    求一个大于等于给定长度的单词有多少,并将其打印出来
    void biggiest(vector<string>v,vector<string>::size_type sz)
    
    在10.3.2节的练习中,编写了一个使用 partition 的biggies版本.使用check_size和bind重写此函数
        //----------这里是本章答案
        auto f1 = bind(check, _1, sz);
        cout << "-------------------------------sort by dic,then bind" << endl;
        auto lstbind = partition(cp3.begin(), cp3.end(), f1);
        for_each(cp3.begin(), lstbind, [](const string &a) { cout << a << ","; });
        cout << endl;
    
    -------------------------------sort by dic
    0,123,1234,99999999999,hello,world,
    -------------------------------sort by dic,then stable_sort by len,then use findif
    1234,hello,world,99999999999,
    -------------------------------sort by dic,then partition
    world,hello,1234,99999999999,
    -------------------------------sort by dic,then stable_partition
    1234,99999999999,hello,world,
    
    
    */
    #include "include.h"
    
    string make_plural(size_t ctr, const string &word, const string &ending)
    {
        return (ctr > 1) ? word + ending : word;
    }
    void elimdups(vector<string> &words)
    {
        sort(words.begin(), words.end());
        auto end_unique = unique(words.begin(), words.end());
        words.erase(end_unique, words.end());
    }
    
    void biggiest2(vector<string> &words, vector<string>::size_type sz)
    {
        elimdups(words); //将words按字典序排序,删除重复词
    
        // 获取一个迭代器,指向最后一个满足size()>=sz的元素之后的位置
        auto wc = partition(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; });
        // 计算满足size()>=sz的元素的数目
        auto count = wc - words.begin();
        cout << count << " " << make_plural(count, "word", "s") << " of length " << sz << " or longer" << endl;
        // 打印长度大于等于给定值的单词,每个单词后面接一个空格
        for_each(words.begin(), wc, [](const string &s) { cout << s << " "; });
        cout << endl;
    }
    
    bool check(const string &a, string::size_type sz)
    {
        return a.size() >= sz;
    }
    
    void biggiest(vector<string> v, vector<string>::size_type sz)
    {
        // 按照字典排序,删除重复单词
        sort(v.begin(), v.end());
        auto last = unique(v.begin(), v.end());
        v.erase(last, v.end());
    
        vector<string> cp1(v);
        vector<string> cp2(v);
        vector<string> cp3(v);
    
        cout << "-------------------------------sort by dic" << endl;
        for_each(cp1.begin(), cp1.end(), [](const string &a) { cout << a << ","; });
        cout << endl;
    
        cout << "-------------------------------sort by dic,then stable_sort by len,then use findif" << endl;
        // 按照长度排序,这里需要传递一个长度 使用lamada
        stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });
        //找到第一个长度>sz的迭代器
        auto fst = find_if(v.begin(), v.end(), [sz](const string &a) { return a.size() >= sz; });
        // 打印vec
        for_each(fst, v.end(), [](const string &a) { cout << a << ","; });
        cout << endl;
    
        //------------------------------------------------------------------------------------------------------------这里是本章答案
        auto f1 = bind(check, _1, sz);
        cout << "-------------------------------sort by dic,then bind" << endl;
        auto lstbind = partition(cp3.begin(), cp3.end(), f1);
        for_each(cp3.begin(), lstbind, [](const string &a) { cout << a << ","; });
        cout << endl;
    
        cout << "-------------------------------sort by dic,then partition" << endl;
        auto lst = partition(cp1.begin(), cp1.end(), [sz](const string &a) { return a.size() >= sz; });
        for_each(cp1.begin(), lst, [](const string &a) { cout << a << ","; });
        cout << endl;
    
        cout << "-------------------------------sort by dic,then stable_partition" << endl;
        auto lst2 = stable_partition(cp2.begin(), cp2.end(), [sz](const string &a) { return a.size() >= sz; });
        for_each(cp2.begin(), lst2, [](const string &a) { cout << a << ","; });
        cout << endl;
    }
    
    int main(int argc, char const *argv[])
    {
        vector<string> v = {"0", "123", "1234", "hello", "world", "99999999999", "world"};
        biggiest(v, 4);
    
        while (1)
            ;
        return 0;
    }
    
    

    10.26

    解释三种插入迭代器的不同之处
    
    back_inserter 总是执行push_back  尾部插入
    front_inserter 执行 push_front  头部插入
    inserter(container,where)  在where前插入后,返回where 也就是原来的迭代器的位置
    

    10.27

    /*
    除了unique之外,标准库还定义了名为unique_copy的函数,
    它接受第三个迭代器,表示拷贝不重复元素的目的位置。
    编写一个程序,使用unique_copy将一个vector中不重复的元素拷贝到一个初始为空的list中
    */
    
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
    
        vector<int> v = {1, 2, 3, 4, 5, 2, 3, 1, 4, 1, 2, 3, 4, 5, 9};
        list<int> l;
    
        sort(v.begin(), v.end());
    
        auto last = unique_copy(v.begin(), v.end(), back_inserter(l));
    
        for_each(l.begin(), l.end(), [](const int &i) { cout << i << " "; });
        cout << endl;
    
        while (1)
            ;
        return 0;
    }
    

    10.28

    /*
    一个vector中保存1到9共9个值,将其拷贝到三个其他容器中。分别使用inserter、back_inserter 和front_inserter将元素添加到三个容器中。
    对每种 inserter,估计输出序列是怎样的,运行程序验证你的估计是否正确  
    */
    
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        vector<int> v;
        list<int> v1;
        list<int> v2;
        list<int> v3;
    
        for (int i = 0; i < 9; i++)
            v.push_back(i);
    
        copy(v.begin(), v.end(), inserter(v1, v1.begin())); // 0,1,2,3,4,5,6,7,8,
        copy(v.begin(), v.end(), back_inserter(v2));        // 0,1,2,3,4,5,6,7,8,
        copy(v.begin(), v.end(), front_inserter(v3));       // 8,7,6,5,4,3,2,1,0,
    
        for_each(v1.begin(), v1.end(), [](const int ch) { cout << ch << ","; });
        cout << endl;
        for_each(v2.begin(), v2.end(), [](const int ch) { cout << ch << ","; });
        cout << endl;
        for_each(v3.begin(), v3.end(), [](const int ch) { cout << ch << ","; });
        cout << endl;
    
        while (1)
            ;
        return 0;
    }
    
    

    10.29

    /*
    编写程序,使用流迭代器读取一个文本文件,存入一个vector中的string里
     1:  vector<string> v(in_iter, eof_f);
     2: copy(in_iter, eof_f, back_inserter(vec));
    
    */
    #include <fstream>
    #include <iterator>
    
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
    
        ifstream in_f("E:\Reading\C++\C+++Primer\CppPrimer-master\CppPrimer\10th\10.29.cpp");
        istream_iterator<string> in_iter(in_f);
        istream_iterator<string> eof_f;
    
        // 方式1
        vector<string> v(in_iter, eof_f);
        for_each(v.begin(), v.end(), [](const string &ch) { cout << ch << endl; });
    
        //方式2
        vector<string> vec;
        copy(in_iter, eof_f, back_inserter(vec));
        std::copy(v.cbegin(), v.cend(), std::ostream_iterator<string>(std::cout, "
    "));
    
        while (1)
            ;
        return 0;
    }
    
    

    10.30

    /*使用流迭代器、sort和copy从标准输入读取一个整数序列,将其排序,并将结果写到标准输出
    */
    #include "include.h"
    #include <iterator>
    
    int main(int argc, char const *argv[])
    {
        istream_iterator<int> in(cin), eof;
        ostream_iterator<int> out(cout, ",");
        vector<int> v(in, eof);
        sort(v.begin(), v.end());
        copy(v.begin(), v.end(), out);
    
        while (1)
            ;
        return 0;
    }
    

    10.31

    /*
    修改前一题的程序,使其只打印不重复的元素。你的程序应使用unique_copy
    */
    
    #include "include.h"
    #include <iterator>
    
    int main(int argc, char const *argv[])
    {
        istream_iterator<int> in(cin), eof;
        ostream_iterator<int> out(cout, ",");
        vector<int> v(in, eof);
        sort(v.begin(), v.end());
        //_copy(v.begin(), v.end(), out);
        unique_copy(v.begin(), v.end(), out);
    
        while (1)
            ;
        return 0;
    }
    

    10.32

    /*
    10.32 重写1.6节的书店程序,使用一个vector保存交易记录,使用不同算法完成处理。使用sort和10.3.1节中的compareIsbn函数来排序交易记录,然后使用find和accumulate求和。
    */
    
    #include "include.h"
    #include "../include/Sales_item.h"
    #include <numeric>
    #include <iterator>
    
    void TestNew()
    {
        cout << "Usage input: name_id[string] ,count[unsigned] , value[doubel]" << endl;
        istream_iterator<Sales_item> in(cin), eof;
        vector<Sales_item> v(in, eof);
        sort(v.begin(), v.end(), compareIsbn);
        for (auto beg = v.cbegin(), end = beg; beg != v.cend(); beg = end)
        {
            end = find_if(beg, v.cend(), [beg](const Sales_item &nextv) { return nextv.isbn() != beg->isbn(); });
            cout << accumulate(beg, end, Sales_item(beg->isbn())) << endl;
        }
    
        // 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(), 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(); });
        //     std::cout << std::accumulate(beg, end, Sales_item(beg->isbn())) << std::endl;
        // }
    }
    
    int TestOld(void)
    {
        cout << "Usage input: name_id[string] ,count[unsigned] , value[doubel]" << endl;
        Sales_item last;
    
        if (cin >> last)
        {
            Sales_item now;
            while (cin >> now)
            {
                if (now.isbn() == last.isbn())
                {
                    last += now;
                }
                else
                {
                    cout << last << endl;
                    last = now;
                }
            }
            cout << now << endl;
        }
        else
        {
            cout << "input err " << endl;
            return -1;
        }
        return 0;
    }
    int main(int argc, char const *argv[])
    {
        //TestOld();
        TestNew();
        while (1)
            ;
        return 0;
    }
    
    

    10.33

    /*
    编写程序,接受三个参数:一个输入文件和两个输出文件的文件名。输入文件保存的应该是整数。
    使用istream_iterator读取输入文件。使用ostream_iterator将奇数写入第一个输出文件,每个值之后都跟一个空格。
    将偶数写入第二个输出文件,每个值都独占一行
    */
    
    #include "include.h"
    #include <fstream>
    #include <iterator>
    
    int main(int argc, char const *argv[])
    {
        const char *path = "D:\0.txt";
        const char *path1 = "D:\1.txt";
        const char *path2 = "D:\2.txt";
    
        ifstream fin(path);
        ofstream fout1(path1);
        ofstream fout2(path2);
    
        if (!fin)
            cout << "open" << path << "faile" << endl;
        if (!fout1)
            cout << "open" << path1 << "faile" << endl;
        if (!fout2)
            cout << "open" << path2 << "faile" << endl;
        if (!fin || !fin || !fout2)
            while (1)
                ;
    
        istream_iterator<int> in(fin), iof;
        ostream_iterator<int> o1(fout1, " ");
        ostream_iterator<int> o2(fout2, "
    ");
    
        while (in != iof)
        {
    
            cout << *in << endl;
            if (*in & 0x01)
            {
                *o1++ = *in;
            }
            else
            {
                *o2++ = *in;
            }
            in++;
        }
    
        fout1.close();
        fout2.close();
        while (1)
            ;
        return 0;
    }
    
    

    10.34

    10.35

    /*
    1. 反向迭代器 逆序输出vector
    2. 普通迭代器 逆序输出
    */
    #include "include.h"
    #include <iterator>
    int main(int argc, char const *argv[])
    {
        vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    
        copy(v.crbegin(), v.crend(), ostream_iterator<int>(cout, ","));
        cout << endl;
    
        //copy(v.crbegin(), v.crend(), ostream_iterator<int>(cout, ","));
        auto beg1 = v.end() - 1;
        for (; beg1 != v.begin(); advance(beg1, -1))
        {
            cout << *beg1 << ",";
        }
        cout << *beg1 << endl;
    
        
    
        while (1)
            ;
        return 0;
    }
    
    

    10.36

    10.37

    /*使用find在一个int的list中查找最后一个值为0的元素。*/
    /*给定一个包含10个元素的vector,将位置3到7之间的元素按逆序拷贝到一个list中*/
    
    #include "include.h"
    int main(int argc, char const *argv[])
    {
        list<int> l = {1, 2, 3, 5, 0, 1, 2, 5, 8, 2, 0, 3, 15};
    
        auto last_zero_it = find(l.crbegin(), l.crend(), 0);
        cout << distance(last_zero_it, l.crend()) << endl;
        for_each(l.cbegin(), last_zero_it.base(), [](const int c) { cout << c << ","; });
        cout << endl;
    
        //////////end   -1  -2
        vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        list<int> l2(v.rend() - 7, v.rend() - 2);
        for_each(l2.cbegin(), l2.cend(), [](const int c) { cout << c << ","; });
    
        //// 另一种方式,但是他这种对于vector不友好,一直在头部插入,对于list无所谓
        ////copy(vec.cbegin() + 3, vec.cbegin() + 8, ret_lst.rbegin());
    
        while (1)
            ;
        return 0;
    }
    

    10.38

    5个迭代器的类别:
    
    迭代器 简述
    输入 只读 解引用在=右侧,用一次,迭代器支持!=,==,++,->
    输出 只写 解引用在=左侧,用一次,迭代器支持++
    前向 只能递增 可以多次读写同一个位置
    双向 能加能减
    随机 +-具体数字 可以使用下标

    10.39

    10.40

    list 双向迭代
    vec   随机迭代器
    
    cop      输入迭代器,输出迭代器
    reverse  需要将范围内的元素反向处理,>>>双向迭代器
    unique	 去除相邻的重复元素,也就是逐一扫描->>>前向
    
    

    10.41

    /*仅根据算法和参数的名字,描述下面每个标准库算法执行什么操作*/
    replace(beg, end, old_val, new_val);					1.替换范围内的old_val元素为 new_val
    replace_if(beg, end, pred, new_val);					2.元素满足pred的条件,替换为new_val
    replace_copy(beg, end, dest, old_val, new_val);			3. 使用copy而非直接替换
    replace_copy_if(beg, end, dest, pred, new_val);			4. 使用copy而非直接替换
    

    10.42

    /*
    使用list代替vector重新实现10.2.3节中的去除重复单词的程序
    */
    
    #include "include.h"
    
    int main(int argc, char const *argv[])
    {
        list<string> l = {"1",
                          "my",
                          "2",
                          "3",
                          "2",
                          "heel",
                          "my"};
        l.sort();
        l.unique();
        for_each(l.begin(), l.end(), [](const string &c) { cout << c << endl; });
        while (1)
            ;
        return 0;
    }
    
  • 相关阅读:
    修改element ui 默认样式最好的解释
    python全栈开发day92-day96 Vue总结
    跨域资源共享 CORS 详解(转自阮一峰博客)
    Vue axios 返回数据绑定到vue对象问题
    Vue爬坑之路
    input标签checkbox选中触发事件的方法
    python中super的理解(转)
    Django时区的解释
    django 视图函数返回queryset对象或日期对象至浏览器ajax接收的写法
    python全栈开发day87~91-整个流程梳理、CRM功能、知识点梳理
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/12179671.html
Copyright © 2020-2023  润新知