• C++11标准模板(STL)- 算法(std::rotate)


    定义于头文件 

     

    算法库提供大量用途的函数(例如查找、排序、计数、操作),它们在元素范围上操作。注意范围定义为 [first, last) ,其中 last 指代要查询或修改的最后元素的后一个元素。

    旋转范围中的元素顺序

    std::rotate

    template< class ForwardIt >
    void      rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );

    (1)(C++11 前)

    template< class ForwardIt >
    ForwardIt rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );

    (C++11 起)
    (C++20 前)
    template< class ForwardIt >

    constexpr ForwardIt

              rotate( ForwardIt first, ForwardIt n_first, ForwardIt last );
    (C++20 起)
    template< class ExecutionPolicy, class ForwardIt >

    ForwardIt rotate( ExecutionPolicy&& policy,

                      ForwardIt first, ForwardIt n_first, ForwardIt last );
    (2)(C++17 起)

    1) 进行元素范围上的左旋转。

    具体而言, std::rotate 交换范围 [first, last) 中的元素,方式满足元素 n_first 成为新范围的首个元素,而 n_first - 1 成为最后元素。

    此函数的前提条件是 [first, n_first)[n_first, last) 为合法范围。

    2) 同 (1) ,但按照 policy 执行。这些重载仅若 std::is_execution_policy_v> 为 true 才参与重载决议。

    参数

    first-原范围的起始
    n_first-应出现在旋转后范围起始的元素
    last-原范围的结尾
    policy-所用的执行策略。细节见执行策略。
    类型要求
    - ForwardIt 必须满足值可交换 (ValueSwappable) 和 遗留向前迭代器 (LegacyForwardIterator) 的要求。
    - 解引用 ForwardIt 结果的类型必须满足可移动赋值 (MoveAssignable) 和可移动构造 (MoveConstructible) 的要求。

    返回值

    (无)

    (C++11 前)

    指向 first 指向的元素所在的新位置的迭代器。等于 first + (last - n_first)

    (C++11 起)

    复杂度

    firstlast 间的距离成线性。

    异常

    拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

    • 若作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 为标准策略之一,则调用 std::terminate 。对于任何其他 ExecutionPolicy ,行为是实现定义的。
    • 若算法无法分配内存,则抛出 std::bad_alloc 。

    可能的实现

    1. template<class ForwardIt>
    2. ForwardIt rotate(ForwardIt first, ForwardIt n_first, ForwardIt last)
    3. {
    4. if(first == n_first) return last;
    5. if(n_first == last) return first;
    6. auto read = n_first;
    7. auto write = first;
    8. auto next_read = first; // "read" 撞击 "last" 时的读取位置
    9. while(read != last) {
    10. if(write == next_read) next_read = read; // 跟踪 "first" 所至
    11. std::iter_swap(write++, read++);
    12. }
    13. // 旋转剩余序列到位置中
    14. (rotate)(write, next_read, last);
    15. return write;
    16. }

    调用示例

    1. #include <iostream>
    2. #include <algorithm>
    3. #include <functional>
    4. #include <vector>
    5. #include <iterator>
    6. using namespace std;
    7. struct Cell
    8. {
    9. int x;
    10. int y;
    11. Cell &operator +=(const Cell &cell)
    12. {
    13. x += cell.x;
    14. y += cell.y;
    15. return *this;
    16. }
    17. };
    18. std::ostream &operator<<(std::ostream &os, const Cell &cell)
    19. {
    20. os << "{" << cell.x << "," << cell.y << "}";
    21. return os;
    22. }
    23. int main()
    24. {
    25. auto func1 = [](Cell & cell, const Cell & t)
    26. {
    27. cell += t;
    28. return cell;
    29. };
    30. Cell cell{99, 100};
    31. Cell t{2, 3};
    32. auto func2 = std::bind(func1, cell, t);
    33. vector<Cell> cells(8);
    34. std::generate(cells.begin(), cells.end(), func2);
    35. std::cout << "original : ";
    36. std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
    37. std::cout << std::endl;
    38. std::rotate(cells.begin(), cells.begin() + cells.size() / 3, cells.end());
    39. std::cout << "simple rotate left : ";
    40. std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
    41. std::cout << std::endl;
    42. std::rotate(cells.rbegin(), cells.rbegin() + cells.size() / 3, cells.rend());
    43. std::cout << "simple rotate right : ";
    44. std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
    45. std::cout << std::endl;
    46. std::rotate(cells.rbegin(), cells.rbegin() + cells.size() / 3, cells.rend());
    47. std::cout << "simple rotate right : ";
    48. std::copy(cells.begin(), cells.end(), std::ostream_iterator<Cell>(std::cout, " "));
    49. std::cout << std::endl;
    50. return 0;
    51. }

    输出

  • 相关阅读:
    VsCode实用插件分享
    python-Template字符串模板的使用
    python基础06——控制流语句:顺序、分支、循环
    一文图解Golang管道Channel
    【Ubuntu20.04】安装XRDP远程桌面服务
    【从零开始的Java开发】1-6-5 集合综合案例:播放器管理
    vertx的学习总结6
    【excel技巧】如何在Excel表格中添加选项按钮?
    棋盘格测距-单目相机(OpenCV/C++)
    工程企业管理软件源码-综合型项目管理软件
  • 原文地址:https://blog.csdn.net/qq_40788199/article/details/127714794