C++算法库 测试代码

// STL算法.cpp : 定义控制台应用程序的入口点。
//最后修改时间:2018/02/13,测试平台 vs2017
/*
STL六个部分
容器:见相关工程,学习上有两个难点:双端队列的实现细节,RBtree实现细节
分配器:allocator,学习版本是侯捷的书,sgi新版本增了继承层次。内存学习的高级主题
算法:本工程,容器无关的算法
适配器:容器/仿函数。基于容器实现的栈,单链表等
迭代器:最好是参考网站内容http://zh.cppreference.com/w/cpp/iterator
仿函数:无对应工程,比较简单,熟悉已有的小函数可以省得造轮子。
*/
//本页完成的是 3.算法。部分C++17的例子尚未提供
//泛型算法及相关辅助函数

#include "stdafx.h"
#include <iterator>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>
#include <list>
#include <iterator>
#include <experimental\filesystem>
#include <array>
#include <functional>
#include <thread>
#include <chrono>
#include <cctype>
#include <random>
#include <forward_list>
#include <cstdlib>
#include <climits>
using namespace std;

template<typename Container>
bool in_quote(const Container& cont, const std::string& s)
{
    return std::search(cont.begin(), cont.end(), s.begin(), s.end()) != cont.end();
}
template <class Container, class Size, class T>
bool consecutive_values(const Container& c, Size count, const T& v)
{
    return std::search_n(std::begin(c), std::end(c), count, v) != std::end(c);
}
template<class ForwardIt>
void selection_sort(ForwardIt begin, ForwardIt end)
{
    for (ForwardIt i = begin; i != end; ++i)
        std::iter_swap(i, std::min_element(i, end));
}
template <class ForwardIt>
void quicksort(ForwardIt first, ForwardIt last)
{
    if (first == last) return;
    auto pivot = *std::next(first, std::distance(first, last) / 2);
    ForwardIt middle1 = std::partition(first, last,
        [pivot](const auto& em) { return em < pivot; });
    ForwardIt middle2 = std::partition(middle1, last,
        [pivot](const auto& em) { return !(pivot < em); });
    quicksort(first, middle1);
    quicksort(middle2, last);
}
template<class ForwardIt, class T, class Compare = std::less<>>
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare comp = {})
{
    // 注意:类型 T 和 Forward 解引用后的类型都必须可隐式转换为
    // 用于 Compare 的 Type1 和 Type2 。
    // 这严格于 lower_bound 要求(见上述)

    first = std::lower_bound(first, last, value, comp);
    return first != last && !comp(value, *first) ? first : last;
}

template<class Iter>
void merge_sort(Iter first, Iter last)
{
    if (last - first > 1) {
        Iter middle = first + (last - first) / 2;
        merge_sort(first, middle);
        merge_sort(middle, last);
        std::inplace_merge(first, middle, last);
    }
}

//例子全部来源于cppreference
int main()
{
    /*泛型算法,超过100个,分为
    *只读算法
    *写容器算法
    *重排算法
    */
    ////////////////////////////////////////
    //只读算法/////////////////////////////
    ////////////////////////////////////////
    {
        //any_of,all_of,none_of
        //检查一定范围之内,是否全部、存在或不存在元素使得谓词为true
        {
            std::vector<int,allocator<int>> v(10, 2);
            std::partial_sum(v.cbegin(), v.cend(), v.begin());//2,4,6....20
            std::cout << "Among the numbers: ";
            std::copy(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;

            if (std::all_of(v.cbegin(), v.cend(), [](int i) { return i % 2 == 0; })) {
                std::cout << "All numbers are even\n";
            }
            if (std::none_of(v.cbegin(), v.cend(), std::bind(std::modulus<int>(),
                std::placeholders::_1, 2))) {
                std::cout << "None of them are odd\n";
            }
            struct DivisibleBy
            {
                const int d;
                DivisibleBy(int n) : d(n) {}
                bool operator()(int n) const { return n % d == 0; }
            };
            if (std::any_of(v.cbegin(), v.cend(), DivisibleBy(7))) {
                std::cout << "At least one number is divisible by 7\n";
            }
        }
        //for_each将一个函数应用于某一范围的元素
        //返回值是参数3,可执行函数std::move(f)
        {
            std::vector<int> nums{ 3, 4, 2, 8, 15, 267 };

            auto print = [](const int& n) { std::cout << " " << n; };

            std::cout << "before:";
            std::for_each(nums.begin(), nums.end(), print);
            std::cout << ‘\n‘;

            std::for_each(nums.begin(), nums.end(), [](int &n) { n++; });

            // 对每个数调用 Sum::operator()
            struct Sum
            {
                Sum() : sum{ 0 } { }
                void operator()(int n) { sum += n; }
                int sum;
            };
            Sum s = std::for_each(nums.begin(), nums.end(), Sum());

            std::cout << "after: ";
            std::for_each(nums.begin(), nums.end(), print);
            std::cout << ‘\n‘;
            std::cout << "sum: " << s.sum << ‘\n‘;
        }
        //for_each_n应用函数对象到序列的首 n 个元素
        //count
        //count_if
        {
            std::vector<int> v{ 1, 2, 3, 4, 4, 3, 7, 8, 9, 10 };

            // 确定 std::vector 中有多少个整数匹配目标值。
            int target1 = 3;
            int target2 = 5;
            int num_items1 = std::count(v.begin(), v.end(), target1);
            int num_items2 = std::count(v.begin(), v.end(), target2);
            std::cout << "number: " << target1 << " count: " << num_items1 << ‘\n‘;
            std::cout << "number: " << target2 << " count: " << num_items2 << ‘\n‘;

            // 用 lambda 表达式计量能被 3 整除的元素数。
            int num_items3 = std::count_if(v.begin(), v.end(), [](int i) {return i % 3 == 0; });
            std::cout << "number divisible by three: " << num_items3 << ‘\n‘;
        }
        //mismatch查找两个范围第一个不同元素的位置
        //返回值是两个迭代器std::make_pair(first1, first2);
        {
            auto mirror_ends=[](const std::string& in)
            {
                return std::string(in.begin(),
                    std::mismatch(in.begin(), in.end(), in.rbegin()).first);
            };
            std::cout << mirror_ends("abXYZba") << ‘\n‘//ab
                << mirror_ends("abca") << ‘\n‘//a
                << mirror_ends("aba") << ‘\n‘;//aba
        }
        //find
        //find_if
        //find_if_not
        {
            int n1 = 3;
            int n2 = 5;

            std::vector<int> v{ 0, 1, 2, 3, 4 };

            auto result1 = std::find(std::begin(v), std::end(v), n1);
            auto result2 = std::find(std::begin(v), std::end(v), n2);

            if (result1 != std::end(v)) {
                std::cout << "v contains: " << n1 << ‘\n‘;
            }
            else {
                std::cout << "v does not contain: " << n1 << ‘\n‘;
            }

            if (result2 != std::end(v)) {
                std::cout << "v contains: " << n2 << ‘\n‘;
            }
            else {
                std::cout << "v does not contain: " << n2 << ‘\n‘;
            }
        }
        //find_end查找一定范围内最后出现的元素序列
        //下列代码用 find_end() 搜索二个不同的数列
        {
            std::vector<int> v{ 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 };
            std::vector<int>::iterator result;

            std::vector<int> t1{ 1, 2, 3 };

            result = std::find_end(v.begin(), v.end(), t1.begin(), t1.end());
            if (result == v.end()) {
                std::cout << "subsequence not found\n";
            }
            else {
                std::cout << "last subsequence is at: "
                    << std::distance(v.begin(), result) << "\n";
            }

            std::vector<int> t2{ 4, 5, 6 };
            result = std::find_end(v.begin(), v.end(), t2.begin(), t2.end());
            if (result == v.end()) {
                std::cout << "subsequence not found\n";
            }
            else {
                std::cout << "last subsequence is at: "
                    << std::distance(v.begin(), result) << "\n";
            }
        }
        //find_first_of查找元素集合中的任意元素
        {
            std::vector<int> v{ 0, 2, 3, 25, 5 };
            std::vector<int> t{ 3, 19, 10, 2 };

            auto result = std::find_first_of(v.begin(), v.end(), t.begin(), t.end());

            if (result == v.end()) {
                std::cout << "no elements of v were equal to 3, 19, 10 or 2\n";
            }
            else {
                std::cout << "found a match at "
                    << std::distance(v.begin(), result) << "\n";
            }
        }
        //adjacent_find查找彼此相邻的两个相同(或其它的关系)的元素
        {
            std::vector<int> v1{ 0, 1, 2, 3, 40, 40, 41, 41, 5 };

            auto i1 = std::adjacent_find(v1.begin(), v1.end());

            if (i1 == v1.end()) {
                std::cout << "no matching adjacent elements\n";
            }
            else {
                std::cout << "the first adjacent pair of equal elements at: "
                    << std::distance(v1.begin(), i1) << ‘\n‘;
            }

            auto i2 = std::adjacent_find(v1.begin(), v1.end(), std::greater<int>());
            if (i2 == v1.end()) {
                std::cout << "The entire vector is sorted in ascending order\n";
            }
            else {
                std::cout << "The last element in the non-decreasing subsequence is at: "
                    << std::distance(v1.begin(), i2) << ‘\n‘;
            }
            /*
                The first adjacent pair of equal elements at : 4
                The last element in the non - decreasing subsequence is at : 7
            */

        }
        //search查找一个元素区间
        {
            std::string str = "why waste time learning, when ignorance is instantaneous?";
            // str.find() 也能使用
            std::cout << std::boolalpha << in_quote(str, "learning") << ‘\n‘
                << in_quote(str, "lemming") << ‘\n‘;

            std::vector<char> vec(str.begin(), str.end());
            std::cout << std::boolalpha << in_quote(vec, "learning") << ‘\n‘
                << in_quote(vec, "lemming") << ‘\n‘;
        }
        //search_n
        {
            const char sequence[] = "1001010100010101001010101";

            std::cout << std::boolalpha;
            std::cout << "Has 4 consecutive zeros: "
                << consecutive_values(sequence, 4, ‘0‘) << ‘\n‘;
            std::cout << "Has 3 consecutive zeros: "
                << consecutive_values(sequence, 3, ‘0‘) << ‘\n‘;
        }
    }
    //写容器/修改容器算法
    {
        //copy
        //copy_if
        {
            std::vector<int> from_vector(10);
            std::iota(from_vector.begin(), from_vector.end(), 0);

            std::vector<int> to_vector;
            std::copy(from_vector.begin(), from_vector.end(),
                std::back_inserter(to_vector));
            // 或可选地,
            //  std::vector<int> to_vector(from_vector.size());
            //  std::copy(from_vector.begin(), from_vector.end(), to_vector.begin());
            // 任一方式都等价于
            //  std::vector<int> to_vector = from_vector;

            std::cout << "to_vector contains: ";

            std::copy(to_vector.begin(), to_vector.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;
        }
        //copy_n复制一定数目的元素到新的位置
        {
            std::string in = "1234567890";
            std::string out;

            std::copy_n(in.begin(), 4, std::back_inserter(out));
            std::cout << out << ‘\n‘;
        }
        //copy_backward按从后往前的顺序复制一个范围内的元素
        //要求BidirectionalIterator
        {
            std::vector<int> from_vector;
            for (int i = 0; i < 10; i++) {
                from_vector.push_back(i);
            }

            std::vector<int> to_vector(15);

            std::copy_backward(from_vector.begin(), from_vector.end(), to_vector.end());

            std::cout << "to_vector contains: ";
            for (auto i : to_vector) {
                std::cout << i << " ";//0 0 0 0 0 0 1 2 3 4 5 6 7 8 9
            }
        }
        //move
        {
            auto f=[](int n)
            {
                std::this_thread::sleep_for(std::chrono::seconds(n));
                std::cout << "thread " << n << " ended" << ‘\n‘;
            };
            std::vector<std::thread> v;
            v.emplace_back(f, 1);
            v.emplace_back(f, 2);
            v.emplace_back(f, 3);
            std::list<std::thread> l;
            // copy() 无法编译,因为 std::thread 不可复制

            std::move(v.begin(), v.end(), std::back_inserter(l));
            for (auto& t : l) t.join();
        }
        //move_backward
        {
            std::vector<std::string> src{ "foo", "bar", "baz" };
            std::vector<std::string> dest(src.size());

            std::cout << "src: ";
            for (const auto &s : src)
                std::cout << s << ‘ ‘;
            std::cout << "\ndest: ";
            for (const auto &s : dest)
                std::cout << s << ‘ ‘;
            std::cout << ‘\n‘;

            std::move_backward(src.begin(), src.end(), dest.end());

            std::cout << "src: ";
            for (const auto &s : src)
                std::cout << s << ‘ ‘;
            std::cout << "\ndest: ";
            for (const auto &s : dest)
                std::cout << s << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //fill
        {
            std::vector<int> v{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            std::fill(v.begin(), v.end(), -1);

            for (auto elem : v) {
                std::cout << elem << " ";
            }
            std::cout << "\n";
        }
        //fill_n基本同上
        //transform将一个函数应用于某一范围的元素
        //和for_each不同的是,它需要指定输出迭代器,且支持2个操作数
        {
            std::string s("hello");
            std::transform(s.begin(), s.end(), s.begin(),
                [](unsigned char c) -> unsigned char { return std::toupper(c); });//#include <cctype>

            std::vector<std::size_t> ordinals;
            std::transform(s.begin(), s.end(), std::back_inserter(ordinals),
                [](unsigned char c) -> std::size_t { return c; });

            std::cout << s << ‘:‘;
            for (auto ord : ordinals) {
                std::cout << ‘ ‘ << ord;
            }
        }
        //generate
        {
            std::vector<int> v(5);
            std::generate(v.begin(), v.end(), [n = 0]() mutable { return n++; });

            std::cout << "v: ";
            for (auto iv : v) {
                std::cout << iv << " ";
            }
            std::cout << "\n";
        }
        //generate_n几乎同上
        //remove
        //remove_if
        {
            std::string str1 = "Text with some   spaces";
            str1.erase(std::remove(str1.begin(), str1.end(), ‘ ‘),
                str1.end());
            std::cout << str1 << ‘\n‘;

            std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
            str2.erase(std::remove_if(str2.begin(),
                str2.end(),
                [](unsigned char x) {return std::isspace(x); }),
                str2.end());
            std::cout << str2 << ‘\n‘;
        }
        //remove_copy
        //remove_copy_if
        {
            std::string str = "Text with some   spaces";
            std::cout << "before: " << str << "\n";

            std::cout << "after:  ";
            std::remove_copy(str.begin(), str.end(),
                std::ostream_iterator<char>(std::cout), ‘ ‘);
            std::cout << ‘\n‘;
        }
        //replace
        //replace_if
        {
            std::array<int, 10> s{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };

            std::replace(s.begin(), s.end(), 8, 88);

            for (int a : s) {
                std::cout << a << " ";//5 7 4 2 88 6 1 9 0 3
            }
            std::cout << ‘\n‘;

            std::replace_if(s.begin(), s.end(),
                std::bind(std::less<int>(), std::placeholders::_1, 5), 55);
            for (int a : s) {
                std::cout << a << " ";//5 7 55 55 88 6 55 9 55 55
            }
            std::cout << ‘\n‘;
        }
        //replace_copy
        //replace_copy_if
        {
            std::vector<int> v{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };
            std::replace_copy_if(v.begin(), v.end(),
                std::ostream_iterator<int>(std::cout, " "),
                [](int n) {return n > 5; }, 99);
            std::cout << ‘\n‘;
        }
        //swap
        //swap_ranges
        {
            std::vector<int> v = { 1, 2, 3, 4, 5 };
            std::list<int> l = { -1, -2, -3, -4, -5 };

            std::swap_ranges(v.begin(), v.begin() + 3, l.begin());

            for (int n : v)
                std::cout << n << ‘ ‘;//-1 -2 -3 4 5
            std::cout << ‘\n‘;
            for (int n : l)
                std::cout << n << ‘ ‘;//1 2 3 -4 -5
            std::cout << ‘\n‘;
        }
        //iter_swap交换给定的迭代器所指向的元素的值。
        {
            std::random_device rd;
            std::mt19937 gen(rd());
            std::uniform_int_distribution<> dist(-10, 10);
            std::vector<int> v;
            generate_n(back_inserter(v), 20, bind(dist, gen));

            std::cout << "Before sort: ";
            copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));

            selection_sort(v.begin(), v.end());

            std::cout << "\nAfter sort: ";
            copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;
        }
        //reverse
        {
            std::vector<int> v{ 1,2,3 };
            std::reverse(std::begin(v), std::end(v));
            for (auto e : v) std::cout << e;
            std::cout << ‘\n‘;

            int a[] = { 4, 5, 6, 7 };
            std::reverse(std::begin(a), std::end(a));
            for (auto e : a) std::cout << e;
        }
        //reverse_copy
        {
            std::vector<int> v({ 1,2,3 });
            for (const auto& value : v) {
                std::cout << value << " ";
            }
            std::cout << ‘\n‘;

            std::vector<int> destination(3);
            std::reverse_copy(std::begin(v), std::end(v), std::begin(destination));
            for (const auto& value : destination) {
                std::cout << value << " ";
            }
            std::cout << ‘\n‘;
        }
        //rotate将区间内的元素旋转
        {
            std::vector<int> v{ 2, 4, 2, 0, 5, 10, 7, 3, 7, 1 };

            std::cout << "before sort:      ";
            for (int n : v)
                std::cout << n << ‘ ‘;
            std::cout << ‘\n‘; //2 4 2 0 5 10 7 3 7 1

            // 插入排序
            for (auto i = v.begin(); i != v.end(); ++i) {
                std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1);
            }

            std::cout << "after sort:       ";
            for (int n : v)
                std::cout << n << ‘ ‘;
            std::cout << ‘\n‘;//0 1 2 2 3 4 5 7 7 10

            // 简单地旋转到左侧
            std::rotate(v.begin(), v.begin() + 1, v.end());

            std::cout << "simple rotate left  : ";
            for (int n : v)
                std::cout << n << ‘ ‘;
            std::cout << ‘\n‘;//1 2 2 3 4 5 7 7 10 0

            // 简单地旋转到右侧
            std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());

            std::cout << "simple rotate right : ";
            for (int n : v)
                std::cout << n << ‘ ‘;
            std::cout << ‘\n‘;//0 1 2 2 3 4 5 7 7 10
        }
        //rotate_copy
        //random_shuffle将范围内的元素随机重新排序
        {
            std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            std::random_device rd;
            std::mt19937 g(rd());

            std::shuffle(v.begin(), v.end(), g);

            std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << "\n";
        }
        //sample,C++17

        //unique删除区间内连续重复的元素
        {
            // 移除重复元素(正常使用)
            std::vector<int> v{ 1,2,3,1,2,3,3,4,5,4,5,6,7 };
            std::sort(v.begin(), v.end()); // 1 1 2 2 3 3 3 4 4 5 5 6 7
            auto last = std::unique(v.begin(), v.end());
            // v 现在保有 {1 2 3 4 5 6 7 x x x x x x} ,其中 ‘x‘ 为不确定
            v.erase(last, v.end());
            for (int i : v)
                std::cout << i << " ";
            std::cout << "\n";

            // 移除连续空格
            std::string s = "wanna go    to      space?";
            auto end = std::unique(s.begin(), s.end(), [](char l, char r) {
                return std::isspace(l) && std::isspace(r) && l == r;
            });
            // s 现在保有 "wanna go to space?xxxxxxxx" ,其中 ‘x‘ 为不确定
            std::cout << std::string(s.begin(), end) << ‘\n‘;
        }
        //unique_copy
    }
    //划分操作
    {
        //is_partitioned判断区间是否被给定的谓词划分
        {
            std::array<int, 9> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            auto is_even = [](int i) { return i % 2 == 0; };
            std::cout.setf(std::ios_base::boolalpha);
            std::cout << std::is_partitioned(v.begin(), v.end(), is_even) << ‘ ‘;

            std::partition(v.begin(), v.end(), is_even);
            std::cout << std::is_partitioned(v.begin(), v.end(), is_even) << ‘ ‘;

            std::reverse(v.begin(), v.end());
            std::cout << std::is_partitioned(v.begin(), v.end(), is_even);

            //false true false
        }
        //partition把一个区间的元素分为两组
        {
            std::vector<int> v = { 0,1,2,3,4,5,6,7,8,9 };
            std::cout << "Original vector:\n    ";
            for (int elem : v) std::cout << elem << ‘ ‘;

            auto it = std::partition(v.begin(), v.end(), [](int i) {return i % 2 == 0; });

            std::cout << "\nPartitioned vector:\n    ";
            std::copy(std::begin(v), it, std::ostream_iterator<int>(std::cout, " "));
            std::cout << " * ";
            std::copy(it, std::end(v), std::ostream_iterator<int>(std::cout, " "));

            std::forward_list<int> fl = { 1, 30, -4, 3, 5, -4, 1, 6, -8, 2, -5, 64, 1, 92 };
            std::cout << "\nUnsorted list:\n    ";
            for (int n : fl) std::cout << n << ‘ ‘;
            std::cout << ‘\n‘;

            quicksort(std::begin(fl), std::end(fl));
            std::cout << "Sorted using quicksort:\n    ";
            for (int fi : fl) std::cout << fi << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //partition_copy
        {
            int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
            int true_arr[5] = { 0 };
            int false_arr[5] = { 0 };

            std::partition_copy(std::begin(arr), std::end(arr), std::begin(true_arr), std::begin(false_arr),
                [](int i) {return i > 5; });

            std::cout << "true_arr: ";
            for (auto it = std::begin(true_arr); it != std::end(true_arr); ++it) {
                std::cout << *it << ‘ ‘;
            }
            std::cout << ‘\n‘;

            std::cout << "false_arr: ";
            for (auto it = std::begin(false_arr); it != std::end(false_arr); ++it) {
                std::cout << *it << ‘ ‘;
            }
            std::cout << ‘\n‘;
        }
        //stable_partition将元素分为两组,同时保留其相对顺序
        {
            std::vector<int> v{ 0, 0, 3, 0, 2, 4, 5, 0, 7 };
            std::stable_partition(v.begin(), v.end(), [](int n) {return n>0; });
            for (int n : v) {
                std::cout << n << ‘ ‘;
            }
            std::cout << ‘\n‘;
        }
        //partition_point
        {
            std::array<int, 9> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            auto is_even = [](int i) { return i % 2 == 0; };
            std::partition(v.begin(), v.end(), is_even);

            auto p = std::partition_point(v.begin(), v.end(), is_even);

            std::cout << "Before partition:\n    ";
            std::copy(v.begin(), p, std::ostream_iterator<int>(std::cout, " "));
            std::cout << "\nAfter partition:\n    ";
            std::copy(p, v.end(), std::ostream_iterator<int>(std::cout, " "));
        }
    }
    //排序操作
    {
        //is_sorted
        /*
        template<class ForwardIt, class Compare>
        bool is_sorted(ForwardIt first, ForwardIt last, Compare comp)
        {
        return std::is_sorted_until(first, last, comp) == last;
        }
        */
        {
            int digits[] = { 3, 1, 4, 1, 5 };

            for (auto i : digits) std::cout << i << ‘ ‘;
            std::cout << ": is_sorted: " << std::boolalpha
                << std::is_sorted(std::begin(digits), std::end(digits)) << ‘\n‘;

            std::sort(std::begin(digits), std::end(digits));

            for (auto i : digits) std::cout << i << ‘ ‘;
            std::cout << ": is_sorted: "
                << std::is_sorted(std::begin(digits), std::end(digits)) << ‘\n‘;
        }
        //is_sorted_until找出最大的已排序子范围
        {
            std::random_device rd;
            std::mt19937 g(rd());
            const int N = 6;
            int nums[N] = { 3, 1, 4, 1, 5, 9 };

            const int min_sorted_size = 4;
            int sorted_size = 0;
            do {
                std::shuffle(nums, nums + N, g);
                int *sorted_end = std::is_sorted_until(nums, nums + N);
                sorted_size = std::distance(nums, sorted_end);

                for (auto i : nums) std::cout << i << ‘ ‘;
                std::cout << " : " << sorted_size << " initial sorted elements\n";
            } while (sorted_size < min_sorted_size);
        }
        //sort
        {
            std::array<int, 10> s = { 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };

            // 用默认的 operator< 排序
            std::sort(s.begin(), s.end());
            for (auto a : s) {
                std::cout << a << " ";
            }
            std::cout << ‘\n‘;

            // 用标准库比较函数对象排序
            std::sort(s.begin(), s.end(), std::greater<int>());
            for (auto a : s) {
                std::cout << a << " ";
            }
            std::cout << ‘\n‘;

            // 用自定义函数对象排序
            struct {
                bool operator()(int a, int b) const
                {
                    return a < b;
                }
            } customLess;
            std::sort(s.begin(), s.end(), customLess);
            for (auto a : s) {
                std::cout << a << " ";
            }
            std::cout << ‘\n‘;

            // 用 lambda 表达式排序
            std::sort(s.begin(), s.end(), [](int a, int b) {
                return b < a;
            });
            for (auto a : s) {
                std::cout << a << " ";
            }
            std::cout << ‘\n‘;
        }
        //partial_sort
        {
            std::array<int, 10> s{ 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };

            std::partial_sort(s.begin(), s.begin() + 3, s.end());
            for (int a : s) {
                std::cout << a << " ";
            }
        }
        //partial_sort_copy对区间内的元素进行复制并部分排序
        {
            std::vector<int> v0{ 4, 2, 5, 1, 3 };
            std::vector<int> v1{ 10, 11, 12 };
            std::vector<int> v2{ 10, 11, 12, 13, 14, 15, 16 };
            std::vector<int>::iterator it;

            it = std::partial_sort_copy(v0.begin(), v0.end(), v1.begin(), v1.end());

            std::cout << "Writing to the smaller vector in ascending order gives: ";
            for (int a : v1) {
                std::cout << a << " ";// 1 2 3
            }
            std::cout << ‘\n‘;
            if (it == v1.end())
                std::cout << "The return value is the end iterator\n";

            it = std::partial_sort_copy(v0.begin(), v0.end(), v2.begin(), v2.end(),
                std::greater<int>());

            std::cout << "Writing to the larger vector in descending order gives: ";
            for (int a : v2) {
                std::cout << a << " ";//5 4 3 2 1 15 16
            }
            std::cout << ‘\n‘ << "The return value is the iterator to " << *it << ‘\n‘;//15
        }
        //stable_sort
        {
            struct Employee {
                Employee(int age, std::string name) : age(age), name(name) { }
                int age;
                std::string name;  // 不参与比较
            };
            std::vector<Employee> v = {
                Employee(108, "Zaphod"),
                Employee(32, "Arthur"),
                Employee(108, "Ford"),
            };

            std::stable_sort(v.begin(), v.end(), [](const Employee &lhs, const Employee &rhs) {
                return lhs.age < rhs.age; });

            for (const Employee &e : v) {
                std::cout << e.age << ", " << e.name << ‘\n‘;
            }
        }
        //nth_element将给定的区间部分排序,确保区间被给定的元素划分
        /*
        nth_element 是部分排序算法,它重排 [first, last) 中元素,使得:
        nth 所指向的元素被更改为假如 {tt|[first, last)}} 已排序则该位置会出现的元素。
        这个新的 nth 元素前的所有元素小于或等于新的 nth 元素后的所有元素。
        */
        {
            std::vector<int> v{ 5, 6, 4, 3, 2, 6, 7, 9, 3 };

            std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end());
            std::cout << "The median is " << v[v.size() / 2] << ‘\n‘;

            std::nth_element(v.begin(), v.begin() + 1, v.end(), std::greater<int>());
            std::cout << "The second largest element is " << v[1] << ‘\n‘;
            //
            //The median is 5
            //The second largest element is 7
        }
    }
    //二分搜索,针对已排序序列
    {
        //lower_bound
        //upper_bound
        {
            std::vector<int> data = { 1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6 };
            //第一个不小于4的iter
            auto lower = std::lower_bound(data.begin(), data.end(), 4);
            //第一个大于4的iter
            auto upper = std::upper_bound(data.begin(), data.end(), 4);

            std::copy(lower, upper, std::ostream_iterator<int>(std::cout, " "));//444

            std::cout << ‘\n‘;

            // 经典二分搜索,仅若存在才返回值

            data = { 1, 2, 4, 6, 9, 10 };

            auto it = binary_find(data.cbegin(), data.cend(), 4); // 选择 ‘5‘ 的 < 将返回 end()

            if (it != data.cend())
                //4 found at index 2
                std::cout << *it << " found at index " << std::distance(data.cbegin(), it);
        }

        //binary_search
        {
            std::vector<int> haystack{ 1, 3, 4, 5, 9 };
            std::vector<int> needles{ 1, 2, 3 };

            for (auto needle : needles) {
                std::cout << "Searching for " << needle << ‘\n‘;
                if (std::binary_search(haystack.begin(), haystack.end(), needle)) {
                    std::cout << "Found " << needle << ‘\n‘;
                }
                else {
                    std::cout << "no dice!\n";
                }
            }
        }
        //equal_range
        {
            struct S
            {
                int number;
                char name;
                // 注意:此比较运算符忽略 name
                bool operator< (const S& s) const { return number < s.number; }
            };
            std::vector<S> vec = { { 1,‘A‘ },{ 2,‘B‘ },{ 2,‘C‘ },{ 2,‘D‘ },{ 4,‘G‘ },{ 3,‘F‘ } };

            S value = { 2, ‘?‘ };

            auto p = std::equal_range(vec.begin(), vec.end(), value);

            for (auto i = p.first; i != p.second; ++i)
                std::cout << i->name << ‘ ‘;

            // 异相比较:
            struct Comp
            {
                bool operator() (const S& s, int i) const { return s.number < i; }
                bool operator() (int i, const S& s) const { return i < s.number; }
            };

            auto p2 = std::equal_range(vec.begin(), vec.end(), 2, Comp{});

            for (auto i = p2.first; i != p2.second; ++i)
                std::cout << i->name << ‘ ‘;
            //B C D B C D
        }
    }
    //集合操作
    {
        //merge
        {
            std::random_device rd;
            std::mt19937 mt(rd());
            std::uniform_int_distribution<> dis(0, 9);

            std::vector<int> v1(10), v2(10);
            std::generate(v1.begin(), v1.end(), std::bind(dis, std::ref(mt)));
            std::generate(v2.begin(), v2.end(), std::bind(dis, std::ref(mt)));

            // 排序
            std::sort(v1.begin(), v1.end());
            std::sort(v2.begin(), v2.end());

            // 输出 v1
            std::cout << "v1 : ";
            std::copy(v1.begin(), v1.end(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;

            // 输出 v2
            std::cout << "v2 : ";
            std::copy(v2.begin(), v2.end(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;

            // 归并
            std::vector<int> dst;
            std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));

            // 输出
            std::cout << "dst: ";
            std::copy(dst.begin(), dst.end(), std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;
        }
        //inplace_merge 就地合并两个有序的区间,注意是有序
        //有点复杂,需要再看一遍,此函数试图分配临时缓冲区。若分配失败,则选择较低效的算法。
        //交换值即可,为什么参考上说要分配缓冲区?
        {
            std::vector<int> v{ 8, 2, -2, 0, 11, 11, 1, 7, 3 };
            merge_sort(v.begin(), v.end());
            for (auto n : v) {
                std::cout << n << ‘ ‘;
            }
            std::cout << ‘\n‘;
        }
        //includes如果一个集合是另外一个集合的子集则返回true
        {
            std::vector<char> v1{ ‘a‘, ‘b‘, ‘c‘, ‘f‘, ‘h‘, ‘x‘ };
            std::vector<char> v2{ ‘a‘, ‘b‘, ‘c‘ };
            std::vector<char> v3{ ‘a‘, ‘c‘ };
            std::vector<char> v4{ ‘g‘ };
            std::vector<char> v5{ ‘a‘, ‘c‘, ‘g‘ };

            for (auto i : v1) std::cout << i << ‘ ‘;
            std::cout << "\nincludes:\n" << std::boolalpha;

            for (auto i : v2) std::cout << i << ‘ ‘;
            std::cout << ": " << std::includes(v1.begin(), v1.end(), v2.begin(), v2.end()) << ‘\n‘;
            for (auto i : v3) std::cout << i << ‘ ‘;
            std::cout << ": " << std::includes(v1.begin(), v1.end(), v3.begin(), v3.end()) << ‘\n‘;
            for (auto i : v4) std::cout << i << ‘ ‘;
            std::cout << ": " << std::includes(v1.begin(), v1.end(), v4.begin(), v4.end()) << ‘\n‘;
            for (auto i : v5) std::cout << i << ‘ ‘;
            std::cout << ": " << std::includes(v1.begin(), v1.end(), v5.begin(), v5.end()) << ‘\n‘;

            auto cmp_nocase = [](char a, char b) {
                return std::tolower(a) < std::tolower(b);
            };

            std::vector<char> v6{ ‘A‘, ‘B‘, ‘C‘ };
            for (auto i : v6) std::cout << i << ‘ ‘;
            std::cout << ": (case-insensitive) "
                << std::includes(v1.begin(), v1.end(), v6.begin(), v6.end(), cmp_nocase)
                << ‘\n‘;
        }
        //set_difference计算两个集合的差集
        {
            std::vector<int> v1{ 1, 2, 5, 5, 5, 9 };
            std::vector<int> v2{ 2, 5, 7 };
            std::vector<int> diff;

            std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
                std::inserter(diff, diff.begin()));

            for (auto i : v1) std::cout << i << ‘ ‘;
            std::cout << "minus ";
            for (auto i : v2) std::cout << i << ‘ ‘;
            std::cout << "is: ";

            for (auto i : diff) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //set_intersection计算两个集合的交集
        {
            std::vector<int> v1{ 1,2,3,4,5,6,7,8 };
            std::vector<int> v2{ 5,  7,  9,10 };
            std::sort(v1.begin(), v1.end());
            std::sort(v2.begin(), v2.end());

            std::vector<int> v_intersection;

            std::set_intersection(v1.begin(), v1.end(),
                v2.begin(), v2.end(),
                std::back_inserter(v_intersection));
            for (int n : v_intersection)
                std::cout << n << ‘ ‘;
        }
        //set_symmetric_difference计算两个集合的对称差
        {
            std::vector<int> v1{ 1,2,3,4,5,6,7,8 };
            std::vector<int> v2{ 5,  7,  9,10 };
            std::sort(v1.begin(), v1.end());
            std::sort(v2.begin(), v2.end());

            std::vector<int> v_symDifference;

            std::set_symmetric_difference(
                v1.begin(), v1.end(),
                v2.begin(), v2.end(),
                std::back_inserter(v_symDifference));

            for (int n : v_symDifference)
                std::cout << n << ‘ ‘;//1 2 3 4 6 8 9 10
        }
        //set_union计算两个集合的并集
        {
            std::vector<int> v1 = { 1, 2, 3, 4, 5 };
            std::vector<int> v2 = { 3, 4, 5, 6, 7 };
            std::vector<int> dest1;

            std::set_union(v1.begin(), v1.end(),
                v2.begin(), v2.end(),
                std::back_inserter(dest1));

            for (const auto &i : dest1) {
                std::cout << i << ‘ ‘;
            }
            std::cout << ‘\n‘;

        }
    }
    //堆操作
    {
        //is_heap检查给定的区间是否为一个堆
        {
            std::vector<int> v{ 3, 1, 4, 1, 5, 9 };

            std::cout << "initially, v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            if (!std::is_heap(v.begin(), v.end())) {
                std::cout << "making heap...\n";
                std::make_heap(v.begin(), v.end());//建堆。
            }

            std::cout << "after make_heap, v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //is_heap_until查找区间中为堆的最大子区间
        {
            std::vector<int> v{ 3, 1, 4, 1, 5, 9 };

            std::make_heap(v.begin(), v.end());

            // 很可能扰乱堆
            v.push_back(2);
            v.push_back(6);

            auto heap_end = std::is_heap_until(v.begin(), v.end());

            std::cout << "all of v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            std::cout << "only heap: ";
            for (auto i = v.begin(); i != heap_end; ++i) std::cout << *i << ‘ ‘;
            std::cout << ‘\n‘;
            //all of v : 9 5 4 1 1 3 2 6
                //only heap : 9 5 4 1 1 3 2
        }
        //make_heap,这个算法很有用,比如leetcode 767,我们需要每次取出最大的两个数,就需要不断地建堆和pop堆
        {
            std::vector<int> v{ 3, 1, 4, 1, 5, 9 };

            std::cout << "initially, v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            std::make_heap(v.begin(), v.end());

            std::cout << "after make_heap, v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            std::pop_heap(v.begin(), v.end());
            auto largest = v.back();
            v.pop_back();
            std::cout << "largest element: " << largest << ‘\n‘;

            std::cout << "after removing the largest element, v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //push_heap
        {
            std::vector<int> v{ 3, 1, 4, 1, 5, 9 };

            std::make_heap(v.begin(), v.end());

            std::cout << "v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            v.push_back(6);

            std::cout << "before push_heap: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            std::push_heap(v.begin(), v.end());

            std::cout << "after push_heap: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //pop_heap
        {
            std::vector<int> v{ 3, 1, 4, 1, 5, 9 };

            std::make_heap(v.begin(), v.end());

            std::cout << "v: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            std::pop_heap(v.begin(), v.end()); // 移动最大元素到结尾

            std::cout << "after pop_heap: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;

            int largest = v.back();
            v.pop_back();  // 实际移出最大元素
            std::cout << "largest element: " << largest << ‘\n‘;

            std::cout << "heap without largest: ";
            for (auto i : v) std::cout << i << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //sort_heap
        {
            std::vector<int> v = { 3, 1, 4, 1, 5, 9 };

            std::make_heap(v.begin(), v.end());

            std::cout << "heap:\t";
            for (const auto &i : v) {
                std::cout << i << ‘ ‘;
            }

            std::sort_heap(v.begin(), v.end());

            std::cout << "\nsorted:\t";
            for (const auto &i : v) {
                std::cout << i << ‘ ‘;
            }
            std::cout << ‘\n‘;
        }
    }
    //最值操作
    {
        //max返回两个元素中的较大者
        {
            std::cout << "larger of 1 and 9999: " << std::max(1, 9999) << ‘\n‘
                << "larger of ‘a‘, and ‘b‘: " << std::max(‘a‘, ‘b‘) << ‘\n‘
                << "longest of \"foo\", \"bar\", and \"hello\": " <<
                std::max({ "foo", "bar", "hello" },
                    [](const std::string& s1, const std::string& s2) {
                return s1.size() < s2.size();
            }) << ‘\n‘;
        }
        //max_element返回区间内的最大元素
        {
            std::vector<int> v{ 3, 1, -14, 1, 5, 9 };
            std::vector<int>::iterator result;

            result = std::max_element(v.begin(), v.end());
            std::cout << "max element at: " << std::distance(v.begin(), result) << ‘\n‘;
            auto abs_compare=[](int a, int b)
            {
                return (std::abs(a) < std::abs(b));
            };
            result = std::max_element(v.begin(), v.end(), abs_compare);
            std::cout << "max element (absolute) at: " << std::distance(v.begin(), result);
        }
        //min
        //min_element
        //minmax
        {
            std::vector<int> v{ 3, 1, 4, 1, 5, 9, 2, 6 };
            std::srand(std::time(0));
            std::pair<int, int> bounds = std::minmax(std::rand() % v.size(),
                std::rand() % v.size());

            std::cout << "v[" << bounds.first << "," << bounds.second << "]: ";
            for (int i = bounds.first; i < bounds.second; ++i) {
                std::cout << v[i] << ‘ ‘;
            }
            std::cout << ‘\n‘;
        }
        //minmax_element
        {
            std::vector<int> v = { 3, 9, 1, 4, 2, 5, 9 };

            auto result = std::minmax_element(v.begin(), v.end());
            std::cout << "min element at: " << (result.first - v.begin()) << ‘\n‘;
            std::cout << "max element at: " << (result.second - v.begin()) << ‘\n‘;
        }
        //clamp
    }
    //比较操作
    {
        //equal
        {
            auto test=[](const std::string& s)
            {
                if (std::equal(s.begin(), s.begin() + s.size() / 2, s.rbegin())) {
                    std::cout << "\"" << s << "\" is a palindrome\n";
                }
                else {
                    std::cout << "\"" << s << "\" is not a palindrome\n";
                }
            };
            test("radar");
            test("hello");
        }
        //lexicographic_compare如果按字典顺序一个区间小于另一个区间,返回true
        {
            std::vector<char> v1{ ‘a‘, ‘b‘, ‘c‘, ‘d‘ };
            std::vector<char> v2{ ‘a‘, ‘b‘, ‘c‘, ‘d‘ };

            std::mt19937 g{ std::random_device{}() };
            while (!std::lexicographical_compare(v1.begin(), v1.end(),
                v2.begin(), v2.end())) {
                for (auto c : v1) std::cout << c << ‘ ‘;
                std::cout << ">= ";
                for (auto c : v2) std::cout << c << ‘ ‘;
                std::cout << ‘\n‘;

                std::shuffle(v1.begin(), v1.end(), g);
                std::shuffle(v2.begin(), v2.end(), g);
            }

            for (auto c : v1) std::cout << c << ‘ ‘;
            std::cout << "< ";
            for (auto c : v2) std::cout << c << ‘ ‘;
            std::cout << ‘\n‘;
        }
        //compare_3way
        //lexicographic_compare_3way
    }
    //排列操作
    {
        //is_permutation
        {
            std::vector<int> v1{ 1,2,3,4,5 };
            std::vector<int> v2{ 3,5,4,1,2 };
            std::cout << "3,5,4,1,2 is a permutation of 1,2,3,4,5? "
                << std::boolalpha
                << std::is_permutation(v1.begin(), v1.end(), v2.begin()) << ‘\n‘;

            std::vector<int> v3{ 3,5,4,1,1 };
            std::cout << "3,5,4,1,1 is a permutation of 1,2,3,4,5? "
                << std::boolalpha
                << std::is_permutation(v1.begin(), v1.end(), v3.begin()) << ‘\n‘;
        }
        //next_permutation 下列代码打印字符串 "aba" 的全部三种排列
        {
            std::string s = "aba";
            std::sort(s.begin(), s.end());
            do {
                std::cout << s << ‘\n‘;
            } while (std::next_permutation(s.begin(), s.end()));
            /*
            输出:aab
            aba
            baa
            */
        }
        //prev_permutation
        {
            std::string s = "abc";
            std::sort(s.begin(), s.end(), std::greater<char>());
            do {
                std::cout << s << ‘ ‘;
            } while (std::prev_permutation(s.begin(), s.end()));
            std::cout << ‘\n‘;
        }
    }
    //数值运算
    {
        //iota用从起始值开始连续递增的值填充区间
        {
            std::list<int> l(10);
            std::iota(l.begin(), l.end(), -4);

            std::vector<std::list<int>::iterator> v(l.size());
            std::iota(v.begin(), v.end(), l.begin());

            std::shuffle(v.begin(), v.end(), std::mt19937{ std::random_device{}() });

            std::cout << "Contents of the list: ";
            for (auto n : l) std::cout << n << ‘ ‘;
            std::cout << ‘\n‘;

            std::cout << "Contents of the list, shuffled: ";
            for (auto i : v) std::cout << *i << ‘ ‘;
            std::cout << ‘\n‘;
            /*
            Contents of the list: -4 -3 -2 -1 0 1 2 3 4 5
            Contents of the list, shuffled: 0 -1 3 4 -4 1 -2 -3 2 5
            */
        }
        //accumulate
        //inner_product内积
        {
            std::vector<int> a{ 0, 1, 2, 3, 4 };
            std::vector<int> b{ 5, 4, 2, 3, 1 };

            int r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0);
            std::cout << "Inner product of a and b: " << r1 << ‘\n‘;//4+4+9+4=21

            //value = op1(value, op2(*first1, *first2));
            int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                std::plus<>(), std::equal_to<>());
            std::cout << "Number of pairwise matches between a and b: " << r2 << ‘\n‘;
        }
        //adjacent_difference计算区间内相邻元素之间的差
        {
            std::vector<int> v{ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
            std::adjacent_difference(v.begin(), v.end(), v.begin());

            for (auto n : v) {
                std::cout << n << ‘ ‘;
            }
            std::cout << ‘\n‘;

            // 斐波那契
            // 注意,列表中下一项是当前迭代的结果

            v = std::vector<int>(10);
            v[0] = 1;

            std::adjacent_difference(v.begin(), v.end() - 1, v.begin() + 1, std::plus<int>());

            for (auto n : v) {
                std::cout << n << ‘ ‘;
            }
            std::cout << ‘\n‘;
        }
        //partial_sum
        {
            std::vector<int> v = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; // 或 std::vector<int>v(10, 2);

            std::cout << "The first 10 even numbers are: ";
            std::partial_sum(v.begin(), v.end(),
                std::ostream_iterator<int>(std::cout, " "));
            std::cout << ‘\n‘;

            std::partial_sum(v.begin(), v.end(), v.begin(), std::multiplies<int>());
            std::cout << "The first 10 powers of 2 are: ";
            for (auto n : v) {
                std::cout << n << " ";
            }
            std::cout << ‘\n‘;
        }
        //reduce类似于accumulate
        {
            std::vector<double> v(10‘000‘007, 0.5);

            {
                auto t1 = std::chrono::high_resolution_clock::now();
                double result = std::accumulate(v.begin(), v.end(), 0.0);
                auto t2 = std::chrono::high_resolution_clock::now();
                std::chrono::duration<double, std::milli> ms = t2 - t1;
                std::cout << std::fixed << "std::accumulate result " << result
                    << " took " << ms.count() << " ms\n";
            }
            //VS尚不支持
            //{
            //    auto t1 = std::chrono::high_resolution_clock::now();
            //    double result = std::reduce(std::execution::par, v.begin(), v.end());
            //    auto t2 = std::chrono::high_resolution_clock::now();
            //    std::chrono::duration<double, std::milli> ms = t2 - t1;
            //    std::cout << "std::reduce result "
            //        << result << " took " << ms.count() << " ms\n";
            //}
        }
        //exclusive_scan尚不支持
        {
        }
        //inclusive_scan尚不支持
    }
    //未初始化内存上的操作
    {
        //uninitialized_copy将范围内的对象复制到未初始化的内存区域
        //本质是调用placementNew
        //::new (static_cast<void*>(std::addressof(*current))) Value(*first);
        {
            std::vector<std::string> v = { "This", "is", "an", "example" };

            std::string* p;
            std::size_t sz;
            std::tie(p, sz) = std::get_temporary_buffer<std::string>(v.size());
            sz = std::min(sz, v.size());

            std::uninitialized_copy(v.begin(), v.begin() + sz, p);

            for (std::string* i = p; i != p + sz; ++i) {
                std::cout << *i << ‘ ‘;
                i->~basic_string<char>();
            }
            std::return_temporary_buffer(p);
        }
        //uninitialized_copy_n
        {
            std::vector<std::string> v = { "This", "is", "an", "example" };

            std::string* p;
            std::size_t sz;
            std::tie(p, sz) = std::get_temporary_buffer<std::string>(v.size());
            sz = std::min(sz, v.size());

            std::uninitialized_copy_n(v.begin(), sz, p);

            for (std::string* i = p; i != p + sz; ++i) {
                std::cout << *i << ‘ ‘;
                i->~basic_string<char>();
            }
            std::return_temporary_buffer(p);
        }
        //uninitialized_fill复制一个对象到以范围定义的未初始化内存区域
        {
            std::string* p;
            std::size_t sz;
            std::tie(p, sz) = std::get_temporary_buffer<std::string>(4);

            std::uninitialized_fill(p, p + sz, "Example");

            for (std::string* i = p; i != p + sz; ++i) {
                std::cout << *i << ‘\n‘;
                i->~basic_string<char>();
            }
            std::return_temporary_buffer(p);
        }
        //uninitialized_fill_n
        //以下均为C++17支持
        //uninitialized_move
        {
            /*可能的实现
            template<class InputIt, class ForwardIt>
            ForwardIt uninitialized_move(InputIt first, InputIt last, ForwardIt d_first)
            {
                typedef typename std::iterator_traits<ForwardIt>::value_type Value;
                ForwardIt current = d_first;
                try {
                    for (; first != last; ++first, (void) ++current) {
                        ::new (static_cast<void*>(std::addressof(*current))) Value(std::move(*first));
                    }
                    return current;
                }
                catch (...) {
                    for (; d_first != current; ++d_first) {
                        d_first->~Value();
                    }
                    throw;
                }
            }
            //关键代码是::new (static_cast<void*>(std::addressof(*current))) Value(std::move(*first));
            //初始化对象时以右值构造
            */
        }
        //uninitialized_move_n
        //uninitialized_default_construct
        //uninitialized_default_construct_n
        //uninitialized_value_construct
        //uninitialized_vaule_construct_n
        //destroy_at
        //destroy
        //destroy_n
    }
    //C库
    {
        //qsort
        //无关乎名称, C++ 、 C 及 POSIX 都不要求此函数用快速排序实现或作出任何复杂度和稳定性保证。
        {
            int a[] = { -2, 99, 0, -743, 2, INT_MIN, 4 };
            constexpr std::size_t size = sizeof a / sizeof *a;

            std::qsort(a, size, sizeof *a, [](const void* a, const void* b)
            {
                int arg1 = *static_cast<const int*>(a);
                int arg2 = *static_cast<const int*>(b);

                if (arg1 < arg2) return -1;
                if (arg1 > arg2) return 1;
                return 0;

                //  返回 (arg1 > arg2) - (arg1 < arg2); // 可行的缩写
                //  返回 arg1 - arg2; // 错误的缩写(若有 INT_MIN 则失败)
            });

            for (int ai : a)
                std::cout << ai << ‘ ‘;
        }
        //bsearch
        {
            const int ARR_SIZE = 8;
            int arr[ARR_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };

            int key1 = 4;
            auto compare=[](const void *ap, const void *bp)
            {
                auto a = static_cast<const int *>(ap);
                auto b = static_cast<const int *>(bp);
                if (*a < *b)
                    return -1;
                else if (*a > *b)
                    return 1;
                else
                    return 0;
            };
            int *p1 = (int *)std::bsearch(&key1, arr, ARR_SIZE, sizeof(arr[0]), compare);
            if (p1)
                std::cout << "value " << key1 << " found at position " << (p1 - arr) << ‘\n‘;
            else
                std::cout << "value " << key1 << " not found\n";

            int key2 = 9;
            int *p2 = (int *)std::bsearch(&key2, arr, ARR_SIZE, sizeof(arr[0]), compare);
            if (p2)
                std::cout << "value " << key2 << " found at position " << (p2 - arr) << ‘\n‘;
            else
                std::cout << "value " << key2 << " not found\n";
        }
    }
    {
        vector<int> vec_int{ 1,2,2,3,3,3,4,4,4,4,5,6,26,17,8,19,10 };
        vector<string> vec_string{ "i","love","you" };
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lsaejn/p/9733729.html

时间: 2024-11-08 20:30:52

C++算法库 测试代码的相关文章

python__标准库 : 测试代码运行时间(timeit)

用 timeit.Timer.timeit() 方法来测试代码的运行时间: from timeit import Timer def t1(): li = [] for i in range(10000): li.append(i) def t2(): li = [] for i in range(10000): li.insert(0, i) T1 = Timer("t1()", "from __main__ import t1") print("app

数据结构之自建算法库——单链表

本文针对数据结构基础系列网络课程(2):线性表中第10课时单链表基本操作的实现,建立单链表数据存储结构基本操作的算法库. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 单链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:linklist.h,包含定义顺序表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef LINKLIST_H_INCLUDED #define LINKLIST_H_INCLUDED typedef

OpenFace库(Tadas Baltrusaitis)中基于Haar Cascade Classifiers进行人脸检测的测试代码

Tadas Baltrusaitis的OpenFace是一个开源的面部行为分析工具,它的源码可以从 https://github.com/TadasBaltrusaitis/OpenFace 下载.OpenFace主要包括面部关键点检测(facial landmard detection).头部姿势估计(head pose estimation).面部动作单元识别(facial action unit recognition).人眼视线方向估计(eye gaze estimation). 编译T

数据结构之自建算法库——二叉树的链式存储及基本运算

本文是数据结构基础系列(6):树和二叉树中第9课时二叉树的基本运算及其实现的例程. 单链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:btree.h,包含定义顺序表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef BTREE_H_INCLUDED #define BTREE_H_INCLUDED #define MaxSize 100 typedef char ElemType; typedef struct node { ElemType data; //

数据结构之自建算法库——稀疏矩阵的三元组表示

本文针对数据结构基础系列网络课程(5):数组与广义表中第3课时稀疏矩阵的三元组表示. 稀疏矩阵的三元组表示相关的算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:tup.h,包含定义稀疏矩阵的三元组表示数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef TUP_H_INCLUDED #define TUP_H_INCLUDED #define M 6 #define N 7 #define MaxSize 100 //矩阵中非零元素最多个数 typedef int Ele

数据结构之自建算法库——广义表

本文针对数据结构基础系列网络课程(5):数组与广义表中第6课时广义表的存储结构及基本运算的实现. 广义算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:glist.h,包含定义稀疏矩阵的三元组表示数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef GLIST_H_INCLUDED #define GLIST_H_INCLUDED typedef char ElemType; typedef struct lnode { int tag; //节点类型标识 union {

数据结构之自建算法库——循环双链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时循环链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:cdlinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CDLINKLIST_H_INCLUDED #define CDLINKLIST_H_INCLUDED //循环双链表基本运算函数 typedef int E

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int ElemT

数据结构之自建算法库——链串

本文针对数据结构基础系列网络课程(4):串中第4课时串的链式存储及其基本操作实现. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 链队算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:liString.h,包含定义链队数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef LISTRING_H_INCLUDED #define LISTRING_H_INCLUDED typedef struct snode { char dat