• C++ <Algorithm>小小总结


    <algorithm>是C++标准程序库中的一个头文件,定义了C++ STL标准中的基础性的算法(均为函数模板)。<algorithm>定义了设计用于元素范围的函数集合。任何对象序列的范围可以通过迭代器或指针访问。

    std::adjacent_find:在序列中查找第一对相邻且值相等的元素;

    std::find: 对一个输入序列,查找第一个等于给定值的元素;

    std::find_end: 查找有B定义的序列在A序列中最后一次出现的位置(B可能是A的子序列);

    std::find_first_of:查找A序列中第一个与序列B中任一元素值相等的元素位置;

    std::find_if: 在序列中返回满足谓词(给定的条件)的第一个元素;

    std::find_if_not:在序列中返回不满足谓词的第一个元素;

    std::all_of: 如果序列中所有元素均满足给定的条件,则返回true;

    std::any_of: 如果序列中存在元素满足给定的条件,则返回true;

    std::none_of: 如果序列中所有元素均不满足给定的条件,则返回true;

    std::binary_search:对一个升序序列做二分搜索,判断序列中是否有与给定值相等的元素;

    std::search: 在序列A中,搜索B首次出现的位置(B可能是A的子序列);

    std::search_n: 在给定序列中,搜索给定值连续出现n次的位置;

    std::copy: 将一个序列中的元素拷贝到新的位置;

    std::copy_backward:把一个序列复制到另一个序列,按照由尾到头顺序依次复制元素;

    std::copy_if: 将一个序列中满足给定条件的元素拷贝到新的位置;

    std::copy_n: 将一个序列中的前n个元素拷贝到新的位置;

    std::count: 返回序列中等于给定值元素的个数;

    std::count_if: 返回序列中满足给定条件的元素的个数;

    std::equal: 比较两个序列的对应元素是否相等;

    std::equal_range:在已排序的序列中,查找元素等于给定值组成的子范围;

    std::lower_bound:在升序的序列中,查找第一个不小于给定值的元素;

    std::upper_bound:在已排序的序列中,查找第一个大于给定值的元素;

    std::fill: 用给定值填充序列中的每个元素;

    std::fill_n: 用给定值填充序列中的n个元素;

    std::for_each: 将指定函数应用于范围内的每一个元素;

    std::generate: 对序列中的每个元素,用依次调用函数gen的返回值赋值;

    std::generate_n:对序列中的n个元素,用依次调用指定函数gen的返回值赋值;

    std::includes: 判断第二个已排序的序列是否全部都出现在第一个已排序的序列中;

    std::inplace_merge:对两个升序的序列执行原地合并,合并后的序列仍保持升序;

    std::merge: 对两个升序的序列合并,结果序列保持升序;

    std::is_heap: 判断序列是否为二叉堆;

    std::is_heap_until:查找第一个不是堆顺序的元素;

    std::make_heap: 对于一个序列,构造一个二叉堆;

    std::pop_heap: 堆的根节点被移除,堆的元素数目减1并保持堆性质;

    std::push_heap: 向堆中增加一个新元素,新元素最初保存在last-1位置;

    std::sort_heap: 对一个堆,执行原地堆排序,得到一个升序结果;

    std::is_partitioned:判断序列是否按指定谓词划分过;

    std::partition: 对序列重排,使得满足谓词的元素位于最前;

    std::partition_copy:输入序列中,满足谓词的元素复制到result_true,其它元素复制到result_false;

    std::partition_point:输入序列已经是partition,折半查找到分界点;

    std::stable_partiton:对序列重排,使得满足谓词的元素在前,不满足谓词的元素在后,且两组元素内部的相对顺序不变;

    std::is_permutation:判断两个序列是否为同一元素的两个排列;

    std::next_permutation:n个元素有n!中排列。这些排列中,规定升序序列为最小排列,降序序列为最大的排列,任意两个排列按照字典序分出大小。该函数返回当前序列作为一个排列按字典序的下一个排列;

    std::prev_permutation:返回当前序列作为一个排列按字典序的上一个排列;

    std::is_sorted: 判断序列是否为升序;

    std::is_sorted_until:查找序列中第一个未排序的元素;

    std::nth_element:对序列重排,使得指定的位置出现的元素就是有序情况下应该在该位置出现的那个元素,且在指定位置之前的元素都小于指定位置元素,在指定位置之后的元素都大于指定位置元素;

    std::partial_sort:对序列进行部分排序;

    std::partial_sort_copy:拷贝部分排序的序列;

    std::sort: 对序列进行排序;

    std::stable_sort:对序列进行稳定排序;

    std::iter_swap: 交换两个迭代器指向的元素;

    std::swap: 交换两个对象,优先使用移动语义;

    std::swap_ranges:交换两个序列中对应元素;

    std::lexicographical_compare:对两个序列做字典比较,如果第一个序列在字典序下小于第二个序列,则返回true;

    std::min: 返回两个值中的最小值;

    std::min_element:返回序列中的最小值;

    std::max: 返回两个值中的最大值;

    std::max_element:返回序列中的最大值;

    std::minmax: 返回由最小值与最大值构成的std::pair;

    std::minmax_element:返回由序列中最小元素与最大元素构成的std::pair;

    std::mismatch: 比较两个序列的对应元素,返回用std::pair表示的第一处不匹配在两个序列的位置;

    std::move: 把输入序列中的逐个元素移动到结果序列;注意与   http://blog.csdn.net/fengbingchun/article/details/52558914 中的不同;

    std::move_backward:把输入序列中的逐个元素自尾到头移动到结果序列;

    std::shuffle: 使用均匀随机数生成器,随机打乱指定范围中的元素的位置;

    std::random_shuffle:n个元素有!n个排列,该函数给出随机选择的一个排列;

    std::remove: 删除序列中等于给定值的所有元素;

    std::remove_if: 删除序列中满足给定谓词的元素;

    std::remove_copy:把一个序列中不等于给定值的元素复制到另一个序列中;

    std::remove_copy_if:把一个序列中不满足给定谓词的元素复制到另一个序列中;

    std::replace: 把序列中等于给定值的元素替换为新值;

    std::replace_if:把序列中满足给定谓词的元素替换为新值;

    std::replace_copy:拷贝序列,对于等于老值的元素复制时使用新值;

    std::replace_copy_if:拷贝序列,对于满足给定谓词的元素复制时使用新值;

    std::reverse: 把序列中的元素逆序;

    std::reverse_copy:拷贝序列的逆序到另一个序列中;

    std::rotate: 等效于循环左移序列,使得迭代器middle所指的元素成为首元素;

    std::rotate_copy:等效于循环左移序列并拷贝到新的序列中,使得迭代器middle所指的元素成为首元素;

    std::set_difference:两个升序序列之差;

    std::set_intersection:两个升序序列的交;

    std::set_symmetric_difference:两个升序序列的对称差;

    std::set_union: 两个升序序列的并;

    std::transform: 对序列中的每一个元素,执行一元操作,结果写入另一序列中;或对两个序列中对应的每一对元素,执行二元操作,结果写入另一序列中;

    std::unique: 对序列中一群连续的相等的元素,仅保留第一个元素;

    std::unique_copy:把一个序列中的元素拷贝到另一个序列,对于一群连续的相等的元素,仅拷贝第一个元素。

       1 #include "algorithm.hpp"
       2 #include <algorithm>
       3 #include <iostream>
       4 #include <vector>
       5 #include <cctype>
       6 #include <array>
       7 #include <ctime>
       8 #include <cstdlib>
       9 #include <string>
      10 #include <random>
      11 #include <chrono>
      12  
      13 // reference: http://www.cplusplus.com/reference/algorithm/
      14  
      15 namespace algorithm_ {
      16  
      17 ///////////////////////////////////////
      18 static bool myfunction(int i, int j) { return (i == j); }
      19 static bool comp_case_insensitive(char c1, char c2) { return (std::tolower(c1) == std::tolower(c2)); }
      20 static bool IsOdd(int i) { return ((i % 2) == 1); }
      21  
      22 int test_algorithm_find()
      23 {
      24 {
      25     int myints[] = { 5, 20, 5, 30, 30, 20, 10, 10, 20 };
      26     std::vector<int> myvector(myints, myints + 8);
      27     std::vector<int>::iterator it;
      28  
      29     // using default comparison:
      30     it = std::adjacent_find(myvector.begin(), myvector.end());
      31  
      32     if (it != myvector.end())
      33         std::cout << "the first pair of repeated elements are: " << *it << '
    '; // 30
      34  
      35     //using predicate comparison:
      36     it = std::adjacent_find(++it, myvector.end(), myfunction);
      37  
      38     if (it != myvector.end())
      39         std::cout << "the second pair of repeated elements are: " << *it << '
    '; // 10
      40 }
      41  
      42 {
      43     // using std::find with array and pointer:
      44     int myints[] = { 10, 20, 30, 40 };
      45     int * p;
      46  
      47     p = std::find(myints, myints + 4, 30);
      48     if (p != myints + 4)
      49         std::cout << "Element found in myints: " << *p << '
    '; // 30
      50     else
      51         std::cout << "Element not found in myints
    ";
      52  
      53     // using std::find with vector and iterator:
      54     std::vector<int> myvector(myints, myints + 4);
      55     std::vector<int>::iterator it;
      56  
      57     it = std::find(myvector.begin(), myvector.end(), 30);
      58     if (it != myvector.end())
      59         std::cout << "Element found in myvector: " << *it << '
    '; // 30
      60     else
      61         std::cout << "Element not found in myvector
    ";
      62 }
      63  
      64 {
      65     int myints[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 };
      66     std::vector<int> haystack(myints, myints + 10);
      67  
      68     int needle1[] = { 1, 2, 3 };
      69  
      70     // using default comparison:
      71     std::vector<int>::iterator it;
      72     it = std::find_end(haystack.begin(), haystack.end(), needle1, needle1 + 3);
      73  
      74     if (it != haystack.end())
      75         std::cout << "needle1 last found at position " << (it - haystack.begin()) << '
    '; // 5
      76  
      77     int needle2[] = { 4, 5, 1 };
      78  
      79     // using predicate comparison:
      80     it = std::find_end(haystack.begin(), haystack.end(), needle2, needle2 + 3, myfunction);
      81  
      82     if (it != haystack.end())
      83         std::cout << "needle2 last found at position " << (it - haystack.begin()) << '
    '; // 3
      84 }
      85  
      86 {
      87     int mychars[] = { 'a', 'b', 'c', 'A', 'B', 'C' };
      88     std::vector<char> haystack(mychars, mychars + 6);
      89     std::vector<char>::iterator it;
      90  
      91     int needle[] = { 'A', 'B', 'C' };
      92  
      93     // using default comparison:
      94     it = find_first_of(haystack.begin(), haystack.end(), needle, needle + 3);
      95  
      96     if (it != haystack.end())
      97         std::cout << "The first match is: " << *it << '
    '; // A
      98  
      99     // using predicate comparison:
     100     it = find_first_of(haystack.begin(), haystack.end(), needle, needle + 3, comp_case_insensitive);
     101  
     102     if (it != haystack.end())
     103         std::cout << "The first match is: " << *it << '
    '; // a
     104 }
     105  
     106 {
     107     std::vector<int> myvector;
     108  
     109     myvector.push_back(10);
     110     myvector.push_back(25);
     111     myvector.push_back(40);
     112     myvector.push_back(55);
     113  
     114     std::vector<int>::iterator it = std::find_if(myvector.begin(), myvector.end(), IsOdd);
     115     std::cout << "The first odd value is " << *it << '
    '; // 25
     116 }
     117  
     118 {
     119     std::array<int, 5> foo = { 1, 2, 3, 4, 5 };
     120  
     121     std::array<int, 5>::iterator it = std::find_if_not(foo.begin(), foo.end(), [](int i){return i % 2; });
     122     std::cout << "The first even value is " << *it << '
    '; // 2
     123 }
     124  
     125     return 0;
     126 }
     127  
     128 ////////////////////////////////////////////
     129 int test_algorithm_all_of()
     130 {
     131 {
     132     std::array<int, 8> foo = { 3, 5, 7, 11, 13, 17, 19, 23 };
     133  
     134     if (std::all_of(foo.begin(), foo.end(), [](int i){return i % 2; }))
     135         std::cout << "All the elements are odd numbers.
    "; // All the elements are odd numbers
     136 }
     137  
     138 {
     139     std::array<int, 7> foo = { 0, 1, -1, 3, -3, 5, -5 };
     140  
     141     if (std::any_of(foo.begin(), foo.end(), [](int i){return i<0; }))
     142         std::cout << "There are negative elements in the range.
    "; // There are negative elements in the range
     143 }
     144  
     145 {
     146     std::array<int, 8> foo = { 1, 2, 4, 8, 16, 32, 64, 128 };
     147  
     148     if (std::none_of(foo.begin(), foo.end(), [](int i){return i<0; }))
     149         std::cout << "There are no negative elements in the range.
    "; // There are no negative elements in the range
     150 }
     151  
     152     return 0;
     153 }
     154  
     155 ////////////////////////////////////////////////
     156 static bool myfunction2(int i, int j) { return (i<j); }
     157 static bool mypredicate(int i, int j) { return (i == j); }
     158  
     159 int test_algorithm_search()
     160 {
     161 {
     162     int myints[] = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
     163     std::vector<int> v(myints, myints + 9);
     164  
     165     // using default comparison:
     166     std::sort(v.begin(), v.end());
     167  
     168     std::cout << "looking for a 3... ";
     169     if (std::binary_search(v.begin(), v.end(), 3)) std::cout << "found!
    "; // found!
     170     else std::cout << "not found.
    ";
     171  
     172     // using myfunction as comp:
     173     std::sort(v.begin(), v.end(), myfunction2);
     174  
     175     std::cout << "looking for a 6... ";
     176     if (std::binary_search(v.begin(), v.end(), 6, myfunction2)) std::cout << "found!
    ";
     177     else std::cout << "not found.
    "; // not found.
     178 }
     179  
     180 {
     181     std::vector<int> haystack;
     182  
     183     // set some values:        haystack: 10 20 30 40 50 60 70 80 90
     184     for (int i = 1; i<10; i++) haystack.push_back(i * 10);
     185  
     186     // using default comparison:
     187     int needle1[] = { 40, 50, 60, 70 };
     188     std::vector<int>::iterator it;
     189     it = std::search(haystack.begin(), haystack.end(), needle1, needle1 + 4);
     190  
     191     if (it != haystack.end())
     192         std::cout << "needle1 found at position " << (it - haystack.begin()) << '
    '; // 3
     193     else
     194         std::cout << "needle1 not found
    ";
     195  
     196     // using predicate comparison:
     197     int needle2[] = { 20, 30, 50 };
     198     it = std::search(haystack.begin(), haystack.end(), needle2, needle2 + 3, mypredicate);
     199  
     200     if (it != haystack.end())
     201         std::cout << "needle2 found at position " << (it - haystack.begin()) << '
    ';
     202     else
     203         std::cout << "needle2 not found
    "; // needle2 not found
     204 }
     205  
     206 {
     207     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
     208     std::vector<int> myvector(myints, myints + 8);
     209  
     210     std::vector<int>::iterator it;
     211  
     212     // using default comparison:
     213     it = std::search_n(myvector.begin(), myvector.end(), 2, 30);
     214  
     215     if (it != myvector.end())
     216         std::cout << "two 30s found at position " << (it - myvector.begin()) << '
    '; // 2
     217     else
     218         std::cout << "match not found
    ";
     219  
     220     // using predicate comparison:
     221     it = std::search_n(myvector.begin(), myvector.end(), 2, 10, mypredicate);
     222  
     223     if (it != myvector.end())
     224         std::cout << "two 10s found at position " << int(it - myvector.begin()) << '
    '; // 5
     225     else
     226         std::cout << "match not found
    ";
     227 }
     228  
     229     return 0;
     230 }
     231  
     232 //////////////////////////////////////////////
     233 int test_algorithm_copy()
     234 {
     235 {
     236     int myints[] = { 10, 20, 30, 40, 50, 60, 70 };
     237     std::vector<int> myvector(7);
     238  
     239     std::copy(myints, myints + 7, myvector.begin());
     240  
     241     std::cout << "myvector contains:";
     242     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     243         std::cout << ' ' << *it; // 10 20 30 40 50 60 70
     244  
     245     std::cout << '
    ';
     246 }
     247  
     248 {
     249     std::vector<int> myvector;
     250  
     251     // set some values:
     252     for (int i = 1; i <= 5; i++)
     253         myvector.push_back(i * 10);          // myvector: 10 20 30 40 50
     254  
     255     myvector.resize(myvector.size() + 3);  // allocate space for 3 more elements
     256  
     257     std::copy_backward(myvector.begin(), myvector.begin() + 5, myvector.end());
     258  
     259     std::cout << "myvector contains:";
     260     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     261         std::cout << ' ' << *it; // 10 20 30 10 20 30 40 50
     262     std::cout << '
    ';
     263 }
     264  
     265 {
     266     std::vector<int> foo = { 25, 15, 5, -5, -15 };
     267     std::vector<int> bar(foo.size());
     268  
     269     // copy only positive numbers:
     270     auto it = std::copy_if(foo.begin(), foo.end(), bar.begin(), [](int i){return !(i<0); });
     271     bar.resize(std::distance(bar.begin(), it));  // shrink container to new size
     272  
     273     std::cout << "bar contains:";
     274     for (int& x : bar) std::cout << ' ' << x; // 25 15 5
     275     std::cout << '
    ';
     276 }
     277  
     278 {
     279     int myints[] = { 10, 20, 30, 40, 50, 60, 70 };
     280     std::vector<int> myvector;
     281  
     282     myvector.resize(7);   // allocate space for 7 elements
     283  
     284     std::copy_n(myints, 7, myvector.begin());
     285  
     286     std::cout << "myvector contains:";
     287     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     288         std::cout << ' ' << *it; // 10 20 30 40 50 60 70
     289  
     290     std::cout << '
    ';
     291 }
     292  
     293     return 0;
     294 }
     295  
     296 ///////////////////////////////////////////////
     297 int test_algorithm_count()
     298 {
     299 {
     300     // counting elements in array:
     301     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };   // 8 elements
     302     int mycount = std::count(myints, myints + 8, 10);
     303     std::cout << "10 appears " << mycount << " times.
    "; // 3
     304  
     305     // counting elements in container:
     306     std::vector<int> myvector(myints, myints + 8);
     307     mycount = std::count(myvector.begin(), myvector.end(), 20);
     308     std::cout << "20 appears " << mycount << " times.
    "; // 3
     309 }
     310  
     311 {
     312     std::vector<int> myvector;
     313     for (int i = 1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9
     314  
     315     int mycount = count_if(myvector.begin(), myvector.end(), IsOdd);
     316     std::cout << "myvector contains " << mycount << " odd values.
    "; // 5
     317 }
     318  
     319     return 0;
     320 }
     321  
     322 //////////////////////////////////////////
     323 static bool mygreater(int i, int j) { return (i>j); }
     324  
     325 int test_algorithm_equal()
     326 {
     327 {
     328     int myints[] = { 20, 40, 60, 80, 100 };               // myints: 20 40 60 80 100
     329     std::vector<int>myvector(myints, myints + 5);       // myvector: 20 40 60 80 100
     330  
     331     // using default comparison:
     332     if (std::equal(myvector.begin(), myvector.end(), myints))
     333         std::cout << "The contents of both sequences are equal.
    "; // equal
     334     else
     335         std::cout << "The contents of both sequences differ.
    ";
     336  
     337     myvector[3] = 81;                                 // myvector: 20 40 60 81 100
     338  
     339     // using predicate comparison:
     340     if (std::equal(myvector.begin(), myvector.end(), myints, mypredicate))
     341         std::cout << "The contents of both sequences are equal.
    ";
     342     else
     343         std::cout << "The contents of both sequences differ.
    "; // differ
     344 }
     345  
     346 {
     347     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
     348     std::vector<int> v(myints, myints + 8);                         // 10 20 30 30 20 10 10 20
     349     std::pair<std::vector<int>::iterator, std::vector<int>::iterator> bounds;
     350  
     351     // using default comparison:
     352     std::sort(v.begin(), v.end());                              // 10 10 10 20 20 20 30 30
     353     bounds = std::equal_range(v.begin(), v.end(), 20);          //          ^        ^
     354  
     355     std::cout << "bounds at positions " << (bounds.first - v.begin()); // 3
     356     std::cout << " and " << (bounds.second - v.begin()) << '
    '; // 6
     357  
     358     // using "mygreater" as comp:
     359     std::sort(v.begin(), v.end(), mygreater);                     // 30 30 20 20 20 10 10 10
     360     bounds = std::equal_range(v.begin(), v.end(), 20, mygreater); //       ^        ^
     361  
     362     std::cout << "bounds at positions " << (bounds.first - v.begin()); // 2
     363     std::cout << " and " << (bounds.second - v.begin()) << '
    '; // 5
     364 }
     365  
     366 {
     367     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
     368     std::vector<int> v(myints, myints + 8);       // 10 20 30 30 20 10 10 20
     369  
     370     std::sort(v.begin(), v.end());                // 10 10 10 20 20 20 30 30
     371  
     372     std::vector<int>::iterator low, up;
     373     low = std::lower_bound(v.begin(), v.end(), 20);
     374     up = std::upper_bound(v.begin(), v.end(), 20);
     375  
     376     std::cout << "lower_bound at position " << (low - v.begin()) << '
    '; // 3
     377     std::cout << "upper_bound at position " << (up - v.begin()) << '
    '; // 6
     378 }
     379  
     380     return 0;
     381 }
     382  
     383 //////////////////////////////////////////
     384 int test_algorithm_fill()
     385 {
     386 {
     387     std::vector<int> myvector(8);                       // myvector: 0 0 0 0 0 0 0 0
     388  
     389     std::fill(myvector.begin(), myvector.begin() + 4, 5);   // myvector: 5 5 5 5 0 0 0 0
     390     std::fill(myvector.begin() + 3, myvector.end() - 2, 8);   // myvector: 5 5 5 8 8 8 0 0
     391  
     392     std::cout << "myvector contains:";
     393     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     394         std::cout << ' ' << *it; // 5 5 5 8 8 8 0 0
     395     std::cout << '
    ';
     396 }
     397  
     398 {
     399     std::vector<int> myvector(8, 10);        // myvector: 10 10 10 10 10 10 10 10
     400  
     401     std::fill_n(myvector.begin(), 4, 20);     // myvector: 20 20 20 20 10 10 10 10
     402     std::fill_n(myvector.begin() + 3, 3, 33);   // myvector: 20 20 20 33 33 33 10 10
     403  
     404     std::cout << "myvector contains:";
     405     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     406         std::cout << ' ' << *it; // 20 20 20 33 33 33 10 10
     407     std::cout << '
    ';
     408 }
     409  
     410     return 0;
     411 }
     412  
     413 ///////////////////////////////////////////
     414 void myfunction3(int i) {  // function:
     415     std::cout << ' ' << i;
     416 }
     417  
     418 struct myclass {           // function object type:
     419     void operator() (int i) { std::cout << ' ' << i; }
     420 } myobject;
     421  
     422 int test_algorithm_for_each()
     423 {
     424     std::vector<int> myvector;
     425     myvector.push_back(10);
     426     myvector.push_back(20);
     427     myvector.push_back(30);
     428  
     429     std::cout << "myvector contains:";
     430     for_each(myvector.begin(), myvector.end(), myfunction3); // 10 20 30
     431     std::cout << '
    ';
     432  
     433     // or:
     434     std::cout << "myvector contains:";
     435     for_each(myvector.begin(), myvector.end(), myobject); // 10 20 30
     436     std::cout << '
    ';
     437  
     438     return 0;
     439 }
     440  
     441 ////////////////////////////////////////////////
     442 // function generator:
     443 int RandomNumber() { return (std::rand() % 100); }
     444  
     445 // class generator:
     446 struct c_unique {
     447     int current;
     448     c_unique() { current = 0; }
     449     int operator()() { return ++current; }
     450 } UniqueNumber;
     451  
     452 int current = 0;
     453 int UniqueNumber2() { return ++current; }
     454  
     455 int test_algorithm_generate()
     456 {
     457 {
     458     std::srand(unsigned(std::time(0)));
     459  
     460     std::vector<int> myvector(8);
     461  
     462     std::generate(myvector.begin(), myvector.end(), RandomNumber);
     463  
     464     std::cout << "myvector contains:";
     465     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     466         std::cout << ' ' << *it;
     467     std::cout << '
    ';
     468  
     469     std::generate(myvector.begin(), myvector.end(), UniqueNumber);
     470  
     471     std::cout << "myvector contains:";
     472     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     473         std::cout << ' ' << *it; // 1 2 3 4 5 6 7 8
     474     std::cout << '
    ';
     475 }
     476  
     477 {
     478     int myarray[9];
     479  
     480     std::generate_n(myarray, 9, UniqueNumber2);
     481  
     482     std::cout << "myarray contains:";
     483     for (int i = 0; i<9; ++i)
     484         std::cout << ' ' << myarray[i]; // 1 2 3 4 5 6 7 8 9
     485     std::cout << '
    ';
     486 }
     487  
     488     return 0;
     489 }
     490  
     491 ////////////////////////////////////////////////
     492 int test_algorithm_includes()
     493 {
     494     int container[] = { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
     495     int continent[] = { 40, 30, 20, 10 };
     496  
     497     std::sort(container, container + 10);
     498     std::sort(continent, continent + 4);
     499  
     500     // using default comparison:
     501     if (std::includes(container, container + 10, continent, continent + 4))
     502         std::cout << "container includes continent!
    "; // container includes continent
     503  
     504     // using myfunction as comp:
     505     if (std::includes(container, container + 10, continent, continent + 4, myfunction2))
     506         std::cout << "container includes continent!
    "; // container includes continent
     507  
     508     return 0;
     509 }
     510  
     511 ///////////////////////////////////////////////////////////
     512 int test_algorithm_merge()
     513 {
     514 {
     515     int first[] = { 5, 10, 15, 20, 25 };
     516     int second[] = { 50, 40, 30, 20, 10 };
     517     std::vector<int> v(10);
     518     std::vector<int>::iterator it;
     519  
     520     std::sort(first, first + 5);
     521     std::sort(second, second + 5);
     522  
     523     it = std::copy(first, first + 5, v.begin());
     524     std::copy(second, second + 5, it);
     525  
     526     std::inplace_merge(v.begin(), v.begin() + 5, v.end());
     527  
     528     std::cout << "The resulting vector contains:";
     529     for (it = v.begin(); it != v.end(); ++it)
     530         std::cout << ' ' << *it; // 5 10 10 15 20 20 25 30 40 50
     531     std::cout << '
    ';
     532 }
     533  
     534 {
     535     int first[] = { 5, 10, 15, 20, 25 };
     536     int second[] = { 50, 40, 30, 20, 10 };
     537     std::vector<int> v(10);
     538  
     539     std::sort(first, first + 5);
     540     std::sort(second, second + 5);
     541     std::merge(first, first + 5, second, second + 5, v.begin());
     542  
     543     std::cout << "The resulting vector contains:";
     544     for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
     545         std::cout << ' ' << *it; // 5 10 10 15 20 20 25 30 40 50
     546     std::cout << '
    ';
     547 }
     548  
     549     return 0;
     550 }
     551  
     552 ////////////////////////////////////////
     553 int test_algorithm_heap()
     554 {
     555 {
     556     std::vector<int> foo{ 9, 5, 2, 6, 4, 1, 3, 8, 7 };
     557  
     558     if (!std::is_heap(foo.begin(), foo.end()))
     559         std::make_heap(foo.begin(), foo.end());
     560  
     561     std::cout << "Popping out elements:";
     562     while (!foo.empty()) {
     563         std::pop_heap(foo.begin(), foo.end());   // moves largest element to back
     564         std::cout << ' ' << foo.back();         // prints back // 9 8 7 6 5 4 3 2 1
     565         foo.pop_back();                         // pops element out of container
     566     }
     567     std::cout << '
    ';
     568 }
     569  
     570 {
     571     std::vector<int> foo{ 2, 6, 9, 3, 8, 4, 5, 1, 7 };
     572  
     573     std::sort(foo.begin(), foo.end());
     574     std::reverse(foo.begin(), foo.end());
     575  
     576     auto last = std::is_heap_until(foo.begin(), foo.end());
     577  
     578     std::cout << "The " << (last - foo.begin()) << " first elements are a valid heap:"; // 9
     579     for (auto it = foo.begin(); it != last; ++it)
     580         std::cout << ' ' << *it; // 9 8 7 6 5 4 3 2 1
     581     std::cout << '
    ';
     582 }
     583  
     584 {
     585     int myints[] = { 10, 20, 30, 5, 15 };
     586     std::vector<int> v(myints, myints + 5);
     587  
     588     std::make_heap(v.begin(), v.end());
     589     std::cout << "initial max heap   : " << v.front() << '
    '; // 30
     590  
     591     std::pop_heap(v.begin(), v.end()); v.pop_back();
     592     std::cout << "max heap after pop : " << v.front() << '
    '; // 20
     593  
     594     v.push_back(99); std::push_heap(v.begin(), v.end());
     595     std::cout << "max heap after push: " << v.front() << '
    '; // 99
     596  
     597     std::sort_heap(v.begin(), v.end());
     598  
     599     std::cout << "final sorted range :";
     600     for (unsigned i = 0; i<v.size(); i++)
     601         std::cout << ' ' << v[i]; // 5 10 15 20 99
     602  
     603     std::cout << '
    ';
     604 }
     605  
     606     return 0;
     607 }
     608  
     609 ////////////////////////////////////////////
     610 int test_algorithm_partition()
     611 {
     612 {
     613     std::array<int, 7> foo{ 1, 2, 3, 4, 5, 6, 7 };
     614  
     615     // print contents:
     616     std::cout << "foo:"; for (int& x : foo) std::cout << ' ' << x;
     617     if (std::is_partitioned(foo.begin(), foo.end(), IsOdd))
     618         std::cout << " (partitioned)
    ";
     619     else
     620         std::cout << " (not partitioned)
    "; // not partitioned
     621  
     622     // partition array:
     623     std::partition(foo.begin(), foo.end(), IsOdd);
     624  
     625     // print contents again:
     626     std::cout << "foo:"; for (int& x : foo) std::cout << ' ' << x; // 1 7 3 5 4 6 2
     627     if (std::is_partitioned(foo.begin(), foo.end(), IsOdd))
     628         std::cout << " (partitioned)
    "; // partitioned
     629     else
     630         std::cout << " (not partitioned)
    ";
     631 }
     632  
     633 {
     634     std::vector<int> myvector;
     635  
     636     // set some values:
     637     for (int i = 1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
     638  
     639     std::vector<int>::iterator bound;
     640     bound = std::partition(myvector.begin(), myvector.end(), IsOdd);
     641  
     642     // print out content:
     643     std::cout << "odd elements:";
     644     for (std::vector<int>::iterator it = myvector.begin(); it != bound; ++it)
     645         std::cout << ' ' << *it; // 1 9 3 7 5
     646     std::cout << '
    ';
     647  
     648     std::cout << "even elements:";
     649     for (std::vector<int>::iterator it = bound; it != myvector.end(); ++it)
     650         std::cout << ' ' << *it; // 6 4 8 2
     651     std::cout << '
    ';
     652 }
     653  
     654 {
     655     std::vector<int> foo{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
     656     std::vector<int> odd, even;
     657  
     658     // resize vectors to proper size:
     659     unsigned n = std::count_if(foo.begin(), foo.end(), IsOdd);
     660     odd.resize(n); even.resize(foo.size() - n);
     661  
     662     // partition:
     663     std::partition_copy(foo.begin(), foo.end(), odd.begin(), even.begin(), IsOdd);
     664  
     665     // print contents:
     666     std::cout << "odd: ";  for (int& x : odd)  std::cout << ' ' << x; std::cout << '
    '; // 1 3 5 7 9
     667     std::cout << "even: "; for (int& x : even) std::cout << ' ' << x; std::cout << '
    '; // 2 4 6 8
     668 }
     669  
     670 {
     671     std::vector<int> foo{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
     672     std::vector<int> odd;
     673  
     674     std::partition(foo.begin(), foo.end(), IsOdd);
     675  
     676     auto it = std::partition_point(foo.begin(), foo.end(), IsOdd);
     677     odd.assign(foo.begin(), it);
     678  
     679     // print contents of odd:
     680     std::cout << "odd:";
     681     for (int& x : odd) std::cout << ' ' << x; // 1 9 3 7 5
     682     std::cout << '
    ';
     683 }
     684  
     685 {
     686     std::vector<int> myvector;
     687  
     688     // set some values:
     689     for (int i = 1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
     690  
     691     std::vector<int>::iterator bound;
     692     bound = std::stable_partition(myvector.begin(), myvector.end(), IsOdd);
     693  
     694     // print out content:
     695     std::cout << "odd elements:";
     696     for (std::vector<int>::iterator it = myvector.begin(); it != bound; ++it)
     697         std::cout << ' ' << *it; // 1 3 5 7 9
     698     std::cout << '
    ';
     699  
     700     std::cout << "even elements:";
     701     for (std::vector<int>::iterator it = bound; it != myvector.end(); ++it)
     702         std::cout << ' ' << *it; // 2 4 6 8
     703     std::cout << '
    ';
     704 }
     705  
     706     return 0;
     707 }
     708  
     709 //////////////////////////////////////
     710 int test_algorithm_permutation()
     711 {
     712 {
     713     std::array<int, 5> foo = { 1, 2, 3, 4, 5 };
     714     std::array<int, 5> bar = { 3, 1, 4, 5, 2 };
     715  
     716     if (std::is_permutation(foo.begin(), foo.end(), bar.begin()))
     717         std::cout << "foo and bar contain the same elements.
    "; // foo and bar contain the same elements
     718 }
     719  
     720 {
     721     int myints[] = { 1, 2, 3 };
     722  
     723     std::sort(myints, myints + 3);
     724  
     725     std::cout << "The 3! possible permutations with 3 elements:
    ";
     726     do {
     727         std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '
    ';
     728     } while (std::next_permutation(myints, myints + 3));
     729  
     730     std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '
    '; // 1 2 3
     731 }
     732  
     733 {
     734     int myints[] = { 1, 2, 3 };
     735  
     736     std::sort(myints, myints + 3);
     737     std::reverse(myints, myints + 3);
     738  
     739     std::cout << "The 3! possible permutations with 3 elements:
    ";
     740     do {
     741         std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '
    ';
     742     } while (std::prev_permutation(myints, myints + 3));
     743  
     744     std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '
    '; // 3 2 1
     745 }
     746  
     747     return 0;
     748 }
     749  
     750 /////////////////////////////////////////////
     751 struct myclass2 {
     752     bool operator() (int i, int j) { return (i<j); }
     753 } myobject2;
     754  
     755 bool compare_as_ints(double i, double j) { return (int(i)<int(j)); }
     756  
     757 int test_algorithm_sort()
     758 {
     759 {
     760     std::array<int, 4> foo{ 2, 4, 1, 3 };
     761  
     762     do {
     763         // try a new permutation:
     764         std::prev_permutation(foo.begin(), foo.end());
     765  
     766         // print range:
     767         std::cout << "foo:";
     768         for (int& x : foo) std::cout << ' ' << x;
     769         std::cout << '
    ';
     770  
     771     } while (!std::is_sorted(foo.begin(), foo.end()));
     772  
     773     std::cout << "the range is sorted!
    ";
     774 }
     775  
     776 {
     777     std::array<int, 4> foo{ 2, 4, 1, 3 };
     778     std::array<int, 4>::iterator it;
     779  
     780     do {
     781         // try a new permutation:
     782         std::prev_permutation(foo.begin(), foo.end());
     783  
     784         // print range:
     785         std::cout << "foo:";
     786         for (int& x : foo) std::cout << ' ' << x;
     787         it = std::is_sorted_until(foo.begin(), foo.end());
     788         std::cout << " (" << (it - foo.begin()) << " elements sorted)
    ";
     789  
     790     } while (it != foo.end());
     791  
     792     std::cout << "the range is sorted!
    ";
     793 }
     794  
     795 {
     796     std::vector<int> myvector;
     797  
     798     // set some values:
     799     for (int i = 1; i<10; i++) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9
     800  
     801     std::random_shuffle(myvector.begin(), myvector.end());
     802  
     803     // using default comparison (operator <):
     804     std::nth_element(myvector.begin(), myvector.begin() + 5, myvector.end());
     805  
     806     // using function as comp
     807     std::nth_element(myvector.begin(), myvector.begin() + 5, myvector.end(), myfunction2);
     808  
     809     // print out content:
     810     std::cout << "myvector contains:";
     811     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     812         std::cout << ' ' << *it; // 1 2 3 4 5 6 7 8 9
     813     std::cout << '
    ';
     814 }
     815  
     816 {
     817     int myints[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
     818     std::vector<int> myvector(myints, myints + 9);
     819  
     820     // using default comparison (operator <):
     821     std::partial_sort(myvector.begin(), myvector.begin() + 5, myvector.end());
     822  
     823     // using function as comp
     824     std::partial_sort(myvector.begin(), myvector.begin() + 5, myvector.end(), myfunction2);
     825  
     826     // print out content:
     827     std::cout << "myvector contains:";
     828     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     829         std::cout << ' ' << *it; // 1 2 3 4 5 9 8 7 6
     830     std::cout << '
    ';
     831 }
     832  
     833 {
     834     int myints[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
     835     std::vector<int> myvector(5);
     836  
     837     // using default comparison (operator <):
     838     std::partial_sort_copy(myints, myints + 9, myvector.begin(), myvector.end());
     839  
     840     // using function as comp
     841     std::partial_sort_copy(myints, myints + 9, myvector.begin(), myvector.end(), myfunction2);
     842  
     843     // print out content:
     844     std::cout << "myvector contains:";
     845     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     846         std::cout << ' ' << *it; // 1 2 3 4 5
     847     std::cout << '
    ';
     848 }
     849  
     850 {
     851     int myints[] = { 32, 71, 12, 45, 26, 80, 53, 33 };
     852     std::vector<int> myvector(myints, myints + 8);               // 32 71 12 45 26 80 53 33
     853  
     854     // using default comparison (operator <):
     855     std::sort(myvector.begin(), myvector.begin() + 4);           //(12 32 45 71)26 80 53 33
     856  
     857     // using function as comp
     858     std::sort(myvector.begin() + 4, myvector.end(), myfunction2); // 12 32 45 71(26 33 53 80)
     859  
     860     // using object as comp
     861     std::sort(myvector.begin(), myvector.end(), myobject2);     //(12 26 32 33 45 53 71 80)
     862  
     863     // print out content:
     864     std::cout << "myvector contains:";
     865     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     866         std::cout << ' ' << *it; // 12 26 32 33 45 53 71 80
     867     std::cout << '
    ';
     868 }
     869  
     870 {
     871     double mydoubles[] = { 3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58 };
     872  
     873     std::vector<double> myvector;
     874  
     875     myvector.assign(mydoubles, mydoubles + 8);
     876  
     877     std::cout << "using default comparison:";
     878     std::stable_sort(myvector.begin(), myvector.end());
     879     for (std::vector<double>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     880         std::cout << ' ' << *it; // 1.32 1.41 1.62 1.73 2.58 2.72 3.14 4.67
     881     std::cout << '
    ';
     882  
     883     myvector.assign(mydoubles, mydoubles + 8);
     884  
     885     std::cout << "using 'compare_as_ints' :";
     886     std::stable_sort(myvector.begin(), myvector.end(), compare_as_ints);
     887     for (std::vector<double>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     888         std::cout << ' ' << *it; // 1.41 1.73 1.32 1.62 2.72 2.58 3.14 4.67
     889     std::cout << '
    ';
     890 }
     891  
     892     return 0;
     893 }
     894  
     895 ////////////////////////////////////////////////////
     896 int test_algorithm_swap()
     897 {
     898 {
     899     int myints[] = { 10, 20, 30, 40, 50 };              //   myints:  10  20  30  40  50
     900     std::vector<int> myvector(4, 99);                   // myvector:  99  99  99  99
     901  
     902     std::iter_swap(myints, myvector.begin());     //   myints: [99] 20  30  40  50
     903                               // myvector: [10] 99  99  99
     904  
     905     std::iter_swap(myints + 3, myvector.begin() + 2); //   myints:  99  20  30 [99] 50
     906                                   // myvector:  10  99 [40] 99
     907  
     908     std::cout << "myvector contains:";
     909     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
     910         std::cout << ' ' << *it; // 10 99 40 99
     911     std::cout << '
    ';
     912 }
     913  
     914 {
     915     int x = 10, y = 20;                              // x:10 y:20
     916     std::swap(x, y);                                 // x:20 y:10
     917  
     918     std::vector<int> foo(4, x), bar(6, y);       // foo:4x20 bar:6x10
     919     std::swap(foo, bar);                         // foo:6x10 bar:4x20
     920  
     921     std::cout << "foo contains:";
     922     for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)
     923         std::cout << ' ' << *it; // 10 10 10 10 10 10
     924     std::cout << '
    ';
     925 }
     926  
     927 {
     928     std::vector<int> foo(5, 10);        // foo: 10 10 10 10 10
     929     std::vector<int> bar(5, 33);        // bar: 33 33 33 33 33
     930  
     931     std::swap_ranges(foo.begin() + 1, foo.end() - 1, bar.begin());
     932  
     933     // print out results of swap:
     934     std::cout << "foo contains:";
     935     for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)
     936         std::cout << ' ' << *it; // 10 33 33 33 10
     937     std::cout << '
    ';
     938  
     939     std::cout << "bar contains:";
     940     for (std::vector<int>::iterator it = bar.begin(); it != bar.end(); ++it)
     941         std::cout << ' ' << *it; // 10 10 10 33 33
     942     std::cout << '
    ';
     943 }
     944  
     945     return 0;
     946 }
     947  
     948 ///////////////////////////////////////////////
     949 static bool mycomp(char c1, char c2) { return std::tolower(c1)<std::tolower(c2); }
     950  
     951 int test_algorithm_lexicographical_compare()
     952 {
     953     char foo[] = "Apple";
     954     char bar[] = "apartment";
     955  
     956     std::cout << std::boolalpha;
     957  
     958     std::cout << "Comparing foo and bar lexicographically (foo<bar):
    ";
     959  
     960     std::cout << "Using default comparison (operator<): ";
     961     std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9); // true
     962     std::cout << '
    ';
     963  
     964     std::cout << "Using mycomp as comparison object: ";
     965     std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9, mycomp); // false
     966     std::cout << '
    ';
     967  
     968     return 0;
     969 }
     970  
     971 //////////////////////////////////////
     972 static bool myfn(int i, int j) { return i<j; }
     973  
     974 int test_algorithm_min_max()
     975 {
     976 {
     977     std::cout << "min(1, 2)==" << std::min(1, 2) << '
    '; // 1
     978     std::cout << "min(2, 1)==" << std::min(2, 1) << '
    '; // 1
     979     std::cout << "min('a', 'z')==" << std::min('a', 'z') << '
    '; // a
     980     std::cout << "min(3.14, 2.72)==" << std::min(3.14, 2.72) << '
    '; // 2.72
     981 }
     982  
     983 {
     984     int myints[] = { 3, 7, 2, 5, 6, 4, 9 };
     985  
     986     // using default comparison:
     987     std::cout << "The smallest element is " << *std::min_element(myints, myints + 7) << '
    '; // 2
     988     std::cout << "The largest element is " << *std::max_element(myints, myints + 7) << '
    '; // 9
     989  
     990     // using function myfn as comp:
     991     std::cout << "The smallest element is " << *std::min_element(myints, myints + 7, myfn) << '
    '; // 2
     992     std::cout << "The largest element is " << *std::max_element(myints, myints + 7, myfn) << '
    '; // 9
     993  
     994     // using object myobj as comp:
     995     std::cout << "The smallest element is " << *std::min_element(myints, myints + 7, myobject2) << '
    '; // 2
     996     std::cout << "The largest element is " << *std::max_element(myints, myints + 7, myobject2) << '
    '; // 9
     997 }
     998  
     999 {
    1000     std::cout << "max(1,2)==" << std::max(1, 2) << '
    '; // 2
    1001     std::cout << "max(2,1)==" << std::max(2, 1) << '
    '; // 2
    1002     std::cout << "max('a','z')==" << std::max('a', 'z') << '
    '; // z
    1003     std::cout << "max(3.14,2.73)==" << std::max(3.14, 2.73) << '
    '; // 3.14
    1004 }
    1005  
    1006 {
    1007     auto result = std::minmax({ 1, 2, 3, 4, 5 });
    1008  
    1009     std::cout << "minmax({1,2,3,4,5}): ";
    1010     std::cout << result.first << ' ' << result.second << '
    '; // 1 5
    1011 }
    1012  
    1013 {
    1014     std::array<int, 7> foo{ 3, 7, 2, 9, 5, 8, 6 };
    1015  
    1016     auto result = std::minmax_element(foo.begin(), foo.end());
    1017  
    1018     // print result:
    1019     std::cout << "min is " << *result.first; // 2
    1020     std::cout << ", at position " << (result.first - foo.begin()) << '
    '; // 2
    1021     std::cout << "max is " << *result.second; // 9
    1022     std::cout << ", at position " << (result.second - foo.begin()) << '
    '; // 3
    1023 }
    1024  
    1025     return 0;
    1026 }
    1027  
    1028 ///////////////////////////////////////////
    1029 int test_algorithm_mismatch()
    1030 {
    1031     std::vector<int> myvector;
    1032     for (int i = 1; i<6; i++) myvector.push_back(i * 10); // myvector: 10 20 30 40 50
    1033  
    1034     int myints[] = { 10, 20, 80, 320, 1024 };                //   myints: 10 20 80 320 1024
    1035  
    1036     std::pair<std::vector<int>::iterator, int*> mypair;
    1037  
    1038     // using default comparison:
    1039     mypair = std::mismatch(myvector.begin(), myvector.end(), myints);
    1040     std::cout << "First mismatching elements: " << *mypair.first; // 30
    1041     std::cout << " and " << *mypair.second << '
    '; // 80
    1042  
    1043     ++mypair.first; ++mypair.second;
    1044  
    1045     // using predicate comparison:
    1046     mypair = std::mismatch(mypair.first, myvector.end(), mypair.second, mypredicate);
    1047     std::cout << "Second mismatching elements: " << *mypair.first; // 40
    1048     std::cout << " and " << *mypair.second << '
    '; // 320
    1049  
    1050     return 0;
    1051 }
    1052  
    1053 //////////////////////////////////////////
    1054 /* The behavior of std::move_backward template is equivalent to:
    1055 template<class BidirectionalIterator1, class BidirectionalIterator2>
    1056 BidirectionalIterator2 move_backward ( BidirectionalIterator1 first,
    1057     BidirectionalIterator1 last,
    1058     BidirectionalIterator2 result )
    1059 {
    1060     while (last!=first) *(--result) = std::move(*(--last));
    1061     return result;
    1062 }
    1063 */
    1064 int test_algorithm_move()
    1065 {
    1066 {
    1067     std::vector<std::string> foo = { "air", "water", "fire", "earth" };
    1068     std::vector<std::string> bar(4);
    1069  
    1070     // moving ranges:
    1071     std::cout << "Moving ranges...
    ";
    1072     std::move(foo.begin(), foo.begin() + 4, bar.begin());
    1073  
    1074     std::cout << "foo contains " << foo.size() << " elements:";// 4
    1075     std::cout << " (each in an unspecified but valid state)";
    1076     std::cout << '
    ';
    1077  
    1078     std::cout << "bar contains " << bar.size() << " elements:"; // 4
    1079     for (std::string& x : bar) std::cout << " [" << x << "]"; // [air] [water] [fire] [earch]
    1080     std::cout << '
    ';
    1081  
    1082     // moving container:
    1083     std::cout << "Moving container...
    ";
    1084     foo = std::move(bar);
    1085  
    1086     std::cout << "foo contains " << foo.size() << " elements:"; // 4
    1087     for (std::string& x : foo) std::cout << " [" << x << "]"; // [air] [water] [fire] [earch]
    1088     std::cout << '
    ';
    1089     std::cout << "bar contains " << bar.size() << " elements" << std::endl; // 0
    1090     //std::cout << "bar is in an unspecified but valid state";
    1091     //std::cout << '
    ';
    1092 }
    1093  
    1094 {
    1095     std::string elems[10] = { "air", "water", "fire", "earth" };
    1096  
    1097     // insert new element at the beginning:
    1098     std::move_backward(elems, elems + 4, elems + 5);
    1099     elems[0] = "ether";
    1100  
    1101     std::cout << "elems contains:";
    1102     for (int i = 0; i<10; ++i)
    1103         std::cout << " [" << elems[i] << "]"; // [ether] [air] [water] [fire] [earch]
    1104     std::cout << '
    ';
    1105 }
    1106  
    1107     return 0;
    1108 }
    1109  
    1110 //////////////////////////////////////////////
    1111 // random generator function:
    1112 int myrandom(int i) { return std::rand() % i; }
    1113  
    1114 int test_algorithm_shuffle()
    1115 {
    1116 {
    1117     std::srand(unsigned(std::time(0)));
    1118     std::vector<int> myvector;
    1119  
    1120     // set some values:
    1121     for (int i = 1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9
    1122  
    1123     // using built-in random generator:
    1124     std::random_shuffle(myvector.begin(), myvector.end());
    1125  
    1126     // using myrandom:
    1127     std::random_shuffle(myvector.begin(), myvector.end(), myrandom);
    1128  
    1129     // print out content:
    1130     std::cout << "myvector contains:";
    1131     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1132         std::cout << ' ' << *it;
    1133  
    1134     std::cout << '
    ';
    1135 }
    1136  
    1137 {
    1138     std::array<int, 5> foo{ 1, 2, 3, 4, 5 };
    1139  
    1140     // obtain a time-based seed:
    1141     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    1142  
    1143     shuffle(foo.begin(), foo.end(), std::default_random_engine(seed));
    1144  
    1145     std::cout << "shuffled elements:";
    1146     for (int& x : foo) std::cout << ' ' << x;
    1147     std::cout << '
    ';
    1148 }
    1149  
    1150     return 0;
    1151 }
    1152  
    1153 //////////////////////////////////////////
    1154 int test_algorithm_remove()
    1155 {
    1156 {
    1157     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };      // 10 20 30 30 20 10 10 20
    1158  
    1159     // bounds of range:
    1160     int* pbegin = myints;                                   // ^
    1161     int* pend = myints + sizeof(myints) / sizeof(int);      // ^                       ^
    1162  
    1163     pend = std::remove(pbegin, pend, 20);                   // 10 30 30 10 10 ?  ?  ?
    1164                                                             // ^              ^
    1165     std::cout << "range contains:";
    1166     for (int* p = pbegin; p != pend; ++p)
    1167         std::cout << ' ' << *p; // 10 30 30 10 10
    1168     std::cout << '
    ';
    1169 }
    1170  
    1171 {
    1172     int myints[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };            // 1 2 3 4 5 6 7 8 9
    1173  
    1174     // bounds of range:
    1175     int* pbegin = myints;                                    // ^
    1176     int* pend = myints + sizeof(myints) / sizeof(int);       // ^                 ^
    1177  
    1178     pend = std::remove_if(pbegin, pend, IsOdd);              // 2 4 6 8 ? ? ? ? ?
    1179                                                              // ^       ^
    1180     std::cout << "the range contains:";
    1181     for (int* p = pbegin; p != pend; ++p)
    1182         std::cout << ' ' << *p; // 2 4 6 8
    1183     std::cout << '
    ';
    1184 }
    1185  
    1186 {
    1187     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };               // 10 20 30 30 20 10 10 20
    1188     std::vector<int> myvector(8);
    1189  
    1190     std::remove_copy(myints, myints + 8, myvector.begin(), 20);      // 10 30 30 10 10 0 0 0
    1191  
    1192     std::cout << "myvector contains:";
    1193     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1194         std::cout << ' ' << *it; // 10 30 30 10 10 0 0 0
    1195     std::cout << '
    ';
    1196 }
    1197  
    1198 {
    1199     int myints[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    1200     std::vector<int> myvector(9);
    1201  
    1202     std::remove_copy_if(myints, myints + 9, myvector.begin(), IsOdd);
    1203  
    1204     std::cout << "myvector contains:";
    1205     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1206         std::cout << ' ' << *it; // 2 4 6 8 0 0 0 0 0
    1207     std::cout << '
    ';
    1208 }
    1209  
    1210     return 0;
    1211 }
    1212  
    1213 //////////////////////////////////////////////
    1214 int test_algorithm_replace()
    1215 {
    1216 {
    1217     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
    1218     std::vector<int> myvector(myints, myints + 8);            // 10 20 30 30 20 10 10 20
    1219  
    1220     std::replace(myvector.begin(), myvector.end(), 20, 99);   // 10 99 30 30 99 10 10 99
    1221  
    1222     std::cout << "myvector contains:";
    1223     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1224         std::cout << ' ' << *it; // 10 99 30 30 99 10 10 99
    1225     std::cout << '
    ';
    1226 }
    1227  
    1228 {
    1229     std::vector<int> myvector;
    1230  
    1231     // set some values:
    1232     for (int i = 1; i<10; i++) myvector.push_back(i);               // 1 2 3 4 5 6 7 8 9
    1233  
    1234     std::replace_if(myvector.begin(), myvector.end(), IsOdd, 0);    // 0 2 0 4 0 6 0 8 0
    1235  
    1236     std::cout << "myvector contains:";
    1237     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1238         std::cout << ' ' << *it; // 0 2 0 4 0 6 0 8 0
    1239     std::cout << '
    ';
    1240 }
    1241  
    1242 {
    1243     int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };
    1244  
    1245     std::vector<int> myvector(8);
    1246     std::replace_copy(myints, myints + 8, myvector.begin(), 20, 99);
    1247  
    1248     std::cout << "myvector contains:";
    1249     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1250         std::cout << ' ' << *it; // 10 99 30 30 99 10 10 99
    1251     std::cout << '
    ';
    1252 }
    1253  
    1254 {
    1255     std::vector<int> foo, bar;
    1256  
    1257     // set some values:
    1258     for (int i = 1; i<10; i++) foo.push_back(i);                         // 1 2 3 4 5 6 7 8 9
    1259  
    1260     bar.resize(foo.size());   // allocate space
    1261     std::replace_copy_if(foo.begin(), foo.end(), bar.begin(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0
    1262  
    1263     std::cout << "bar contains:";
    1264     for (std::vector<int>::iterator it = bar.begin(); it != bar.end(); ++it)
    1265         std::cout << ' ' << *it; // 0 2 0 4 0 6 0 8 0
    1266     std::cout << '
    ';
    1267 }
    1268  
    1269     return 0;
    1270 }
    1271  
    1272 ///////////////////////////////////////////////////
    1273 int test_algorithm_reverse()
    1274 {
    1275 {
    1276     std::vector<int> myvector;
    1277  
    1278     // set some values:
    1279     for (int i = 1; i<10; ++i) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9
    1280  
    1281     std::reverse(myvector.begin(), myvector.end());     // 9 8 7 6 5 4 3 2 1
    1282  
    1283     // print out content:
    1284     std::cout << "myvector contains:";
    1285     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1286         std::cout << ' ' << *it; // 9 8 7 6 5 4 3 2 1
    1287     std::cout << '
    ';
    1288 }
    1289  
    1290 {
    1291     int myints[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    1292     std::vector<int> myvector;
    1293  
    1294     myvector.resize(9);    // allocate space
    1295  
    1296     std::reverse_copy(myints, myints + 9, myvector.begin());
    1297  
    1298     // print out content:
    1299     std::cout << "myvector contains:";
    1300     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1301         std::cout << ' ' << *it; // 9 8 7 6 5 4 3 2 1
    1302  
    1303     std::cout << '
    ';
    1304 }
    1305  
    1306     return 0;
    1307 }
    1308  
    1309 ////////////////////////////////////////////
    1310 /*
    1311 The behavior of std::rotate template (C++98) is equivalent to:
    1312 template <class ForwardIterator>
    1313 void rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last)
    1314 {
    1315     ForwardIterator next = middle;
    1316     while (first!=next) {
    1317         swap (*first++,*next++);
    1318         if (next==last) next=middle;
    1319         else if (first==middle) middle=next;
    1320     }
    1321 }
    1322 */
    1323  
    1324 int test_algorithm_rotate()
    1325 {
    1326 {
    1327     std::vector<int> myvector;
    1328  
    1329     // set some values:
    1330     for (int i = 1; i<10; ++i) myvector.push_back(i);                    // 1 2 3 4 5 6 7 8 9
    1331  
    1332     std::rotate(myvector.begin(), myvector.begin() + 3, myvector.end()); // 4 5 6 7 8 9 1 2 3
    1333     // print out content:
    1334     std::cout << "myvector contains:";
    1335     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1336         std::cout << ' ' << *it; // 4 5 6 7 8 9 1 2 3
    1337     std::cout << '
    ';
    1338 }
    1339  
    1340 {
    1341     int myints[] = { 10, 20, 30, 40, 50, 60, 70 };
    1342  
    1343     std::vector<int> myvector(7);
    1344  
    1345     std::rotate_copy(myints, myints + 3, myints + 7, myvector.begin());
    1346  
    1347     // print out content:
    1348     std::cout << "myvector contains:";
    1349     for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
    1350         std::cout << ' ' << *it; // 40 50 60 70 10 20 30
    1351     std::cout << '
    ';
    1352 }
    1353  
    1354     return 0;
    1355 }
    1356  
    1357 //////////////////////////////////////
    1358 /*
    1359 The behavior of std::set_difference template is equivalent to:
    1360 template <class InputIterator1, class InputIterator2, class OutputIterator>
    1361 OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1,
    1362     InputIterator2 first2, InputIterator2 last2, OutputIterator result)
    1363 {
    1364     while (first1!=last1 && first2!=last2) {
    1365         if (*first1<*first2) { *result = *first1; ++result; ++first1; }
    1366         else if (*first2<*first1) ++first2;
    1367         else { ++first1; ++first2; }
    1368     }
    1369     return std::copy(first1,last1,result);
    1370 }
    1371 */
    1372  
    1373 int test_algorithm_set()
    1374 {
    1375 {
    1376     int first[] = { 5, 10, 15, 20, 25 };
    1377     int second[] = { 50, 40, 30, 20, 10 };
    1378     std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
    1379     std::vector<int>::iterator it;
    1380  
    1381     std::sort(first, first + 5);     //  5 10 15 20 25
    1382     std::sort(second, second + 5);   // 10 20 30 40 50
    1383  
    1384     it = std::set_difference(first, first + 5, second, second + 5, v.begin());
    1385                                //  5 15 25  0  0  0  0  0  0  0
    1386     v.resize(it - v.begin());                      //  5 15 25
    1387  
    1388     std::cout << "The difference has " << (v.size()) << " elements:
    "; // 3
    1389     for (it = v.begin(); it != v.end(); ++it)
    1390         std::cout << ' ' << *it; // 5 15 25
    1391     std::cout << '
    ';
    1392 }
    1393  
    1394 {
    1395     int first[] = { 5, 10, 15, 20, 25 };
    1396     int second[] = { 50, 40, 30, 20, 10 };
    1397     std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
    1398     std::vector<int>::iterator it;
    1399  
    1400     std::sort(first, first + 5);     //  5 10 15 20 25
    1401     std::sort(second, second + 5);   // 10 20 30 40 50
    1402  
    1403     it = std::set_intersection(first, first + 5, second, second + 5, v.begin());
    1404                                                    // 10 20 0  0  0  0  0  0  0  0
    1405     v.resize(it - v.begin());                      // 10 20
    1406  
    1407     std::cout << "The intersection has " << (v.size()) << " elements:
    "; // 2
    1408     for (it = v.begin(); it != v.end(); ++it)
    1409         std::cout << ' ' << *it; // 10 20
    1410     std::cout << '
    ';
    1411 }
    1412  
    1413 {
    1414     int first[] = { 5, 10, 15, 20, 25 };
    1415     int second[] = { 50, 40, 30, 20, 10 };
    1416     std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
    1417     std::vector<int>::iterator it;
    1418  
    1419     std::sort(first, first + 5);     //  5 10 15 20 25
    1420     std::sort(second, second + 5);   // 10 20 30 40 50
    1421  
    1422     it = std::set_symmetric_difference(first, first + 5, second, second + 5, v.begin());
    1423                                //  5 15 25 30 40 50  0  0  0  0
    1424     v.resize(it - v.begin());                      //  5 15 25 30 40 50
    1425  
    1426     std::cout << "The symmetric difference has " << (v.size()) << " elements:
    "; // 6
    1427     for (it = v.begin(); it != v.end(); ++it)
    1428         std::cout << ' ' << *it; // 5 15 25 30 40 50
    1429     std::cout << '
    ';
    1430 }
    1431  
    1432 {
    1433     int first[] = { 5, 10, 15, 20, 25 };
    1434     int second[] = { 50, 40, 30, 20, 10 };
    1435     std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
    1436     std::vector<int>::iterator it;
    1437  
    1438     std::sort(first, first + 5);     //  5 10 15 20 25
    1439     std::sort(second, second + 5);   // 10 20 30 40 50
    1440  
    1441     it = std::set_union(first, first + 5, second, second + 5, v.begin());
    1442                                // 5 10 15 20 25 30 40 50  0  0
    1443     v.resize(it - v.begin());                      // 5 10 15 20 25 30 40 50
    1444  
    1445     std::cout << "The union has " << (v.size()) << " elements:
    "; // 8
    1446     for (it = v.begin(); it != v.end(); ++it)
    1447         std::cout << ' ' << *it; // 5 10 15 20 25 30 40 50
    1448     std::cout << '
    ';
    1449 }
    1450  
    1451     return 0;
    1452 }
    1453  
    1454 /////////////////////////////////////
    1455 int op_increase(int i) { return ++i; }
    1456  
    1457 int test_algorithm_transform()
    1458 {
    1459     std::vector<int> foo;
    1460     std::vector<int> bar;
    1461  
    1462     // set some values:
    1463     for (int i = 1; i<6; i++)
    1464         foo.push_back(i * 10);                         // foo: 10 20 30 40 50
    1465  
    1466     bar.resize(foo.size());                         // allocate space
    1467  
    1468     std::transform(foo.begin(), foo.end(), bar.begin(), op_increase);
    1469                                                            // bar: 11 21 31 41 51
    1470  
    1471     // std::plus adds together its two arguments:
    1472     std::transform(foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
    1473                                                            // foo: 21 41 61 81 101
    1474  
    1475     std::cout << "foo contains:";
    1476     for (std::vector<int>::iterator it = foo.begin(); it != foo.end(); ++it)
    1477         std::cout << ' ' << *it; // 21 41 61 81 101
    1478     std::cout << '
    ';
    1479  
    1480     return 0;
    1481 }
    1482  
    1483 /////////////////////////////////////////
    1484 int test_algorithm_unique()
    1485 {
    1486 {
    1487     int myints[] = { 10, 20, 20, 20, 30, 30, 20, 20, 10 };           // 10 20 20 20 30 30 20 20 10
    1488     std::vector<int> myvector(myints, myints + 9);
    1489  
    1490     // using default comparison:
    1491     std::vector<int>::iterator it;
    1492     it = std::unique(myvector.begin(), myvector.end());              // 10 20 30 20 10 ?  ?  ?  ?
    1493                                                                      //                ^
    1494  
    1495     myvector.resize(std::distance(myvector.begin(), it));            // 10 20 30 20 10
    1496  
    1497     // using predicate comparison:
    1498     std::unique(myvector.begin(), myvector.end(), myfunction);   // (no changes)
    1499  
    1500     // print out content:
    1501     std::cout << "myvector contains:";
    1502     for (it = myvector.begin(); it != myvector.end(); ++it)
    1503         std::cout << ' ' << *it; // 10 20 30 20 10
    1504     std::cout << '
    ';
    1505 }
    1506  
    1507 {
    1508     int myints[] = { 10, 20, 20, 20, 30, 30, 20, 20, 10 };
    1509     std::vector<int> myvector(9);                                   // 0  0  0  0  0  0  0  0  0
    1510  
    1511     // using default comparison:
    1512     std::vector<int>::iterator it;
    1513     it = std::unique_copy(myints, myints + 9, myvector.begin());   // 10 20 30 20 10 0  0  0  0
    1514                                                                    //                ^
    1515  
    1516     std::sort(myvector.begin(), it);                               // 10 10 20 20 30 0  0  0  0
    1517                                                                    //                ^
    1518  
    1519     // using predicate comparison:
    1520     it = std::unique_copy(myvector.begin(), it, myvector.begin(), myfunction);
    1521                                                                    // 10 20 30 20 30 0  0  0  0
    1522                                                                    //          ^
    1523  
    1524     myvector.resize(std::distance(myvector.begin(), it));    // 10 20 30
    1525  
    1526     // print out content:
    1527     std::cout << "myvector contains:";
    1528     for (it = myvector.begin(); it != myvector.end(); ++it)
    1529         std::cout << ' ' << *it; // 10 20 30
    1530     std::cout << '
    ';
    1531 }
    1532  
    1533     return 0;
    1534 }
    1535  
    1536 } // namespace algorithm_
  • 相关阅读:
    状态模式
    策略模式Strategy(对象行为型)
    模板方法模式
    Java_观察者模式(Observable和Observer) -转
    Cordova自定义插件
    MongoVUE查询备忘
    C#关于HttpClient的统一配置(一)
    C#邮件收发
    WebApi统一输出接口
    移动开发兼容性问题及性能优化
  • 原文地址:https://www.cnblogs.com/jian-99/p/9645497.html
Copyright © 2020-2023  润新知