C++初学者指南-5.标准库(第二部分)--序列重新排序算法

C++初学者指南-5.标准库(第二部分)–序列重新排序算法


不熟悉 C++ 的标准库算法? ⇒ 简介

移位元素

reverse / reverse_copy

在这里插入图片描述
cppreferencecp

std::vector<int> v {0,1,2,4,6,8,9,3,5};
// reverse subrange (as shown in image):
reverse(begin(v)+2, begin(v)+7);  
for (int x : v) { cout << x << ' '; }  // 0 1 9 8 6 4 2 3 5
// reverse entire vector:
reverse(begin(v), end(v));  
for (int x : v) { cout << x << ' '; }  // 5 3 2 4 6 8 9 1 0

运行示例代码
在这里插入图片描述

std::vector<int> v {2,4,6,8,9};
std::ranges::reverse(v);
for (int x : v) { cout << x << ' '; }  // 9 8 6 4 2

运行示例代码
在这里插入图片描述
输出必须能够接收与输入范围中元素数量相同的元素。
cppreferencecp

std::vector<int> in {0,1,2,4,6,8,9,3,5};
std::vector<int> out; 
out.resize(5);
reverse_copy(begin(in)+2, begin(in)+7, begin(out));
for (int x : out) { cout << x << ' '; }  // 9 8 6 4 2

运行示例代码

在这里插入图片描述
输出必须能够接收与输入范围中元素数量相同的元素。

std::vector<int> in {2,4,6,8,9};
std::vector<int> out; 
out.resize(in.size());
std::ranges::reverse_copy(in, begin(out));
for (int x : out) { cout << x <<' '; }  // 9 8 6 4 2

运行示例代码

rotate / rotate_copy

在这里插入图片描述
执行一个循环左移:所有从开头到新第一元素之前的元素都被移到最后一个元素之后。
cppreferencecp

std::vector<int> v {1,2,3,4,5,6,7};
auto i = rotate(begin(v), begin(v)+2, end(v));  
for (int x : v) { cout << x <<' '; }  // 3 4 5 6 7 1 2
// returned iterator refers to old first:
auto const value = *i;  // 1
auto const index = distance(begin(v), i);  // 5

运行示例代码

在这里插入图片描述
cppreferencecp

std::vector<int> v {1,2,3,4,5,6,7};
auto sub = std::ranges::rotate(v, begin(v)+4);  
for (int x : v)   { cout << x <<' '; }  // 5 6 7 1 2 3 4
for (int x : sub) { cout << x <<' '; }  // 1 2 3 4

运行示例代码

在这里插入图片描述
输出必须能够接收与输入范围中元素数量相同的元素。
cppreferencecp

std::vector<int> in {1,2,3,4,5,6,7};
std::vector<int> out; 
out.resize(in.size());
rotate_copy(begin(in), begin(in)+2, end(in), begin(out));  
for (int x : out) { cout << x <<' '; }  // 3 4 5 6 7 1 2

在这里插入图片描述
输出必须能够接收与输入范围中元素数量相同的元素。
cppreferencecp

std::vector<int> in {1,2,3,4,5,6,7};
std::vector<int> out; 
out.resize(in.size());
std::ranges::rotate_copy(in, begin(in)+4, begin(out));  
for (int x : out) { cout << x <<' '; }  // 5 6 7 1 2 3 4

运行示例代码

shift_left

在这里插入图片描述
cppreferencecp

std::vector<int> v {1,2,3,4,5,6,7,8};
int const by = 3;
shift_left(begin(v), end(v), by);  
for (int x : v) { cout << x <<' '; }  // 4 5 6 7 8 ? ? ?

运行示例代码
在这里插入图片描述
cppreferencecp

std::vector<int> v {1,2,3,4,5,6,7,8};
int const by = 3;
auto result = ranges::shift_left(v, by);  
for (int x : result) { cout << x <<' '; }  // 4 5 6 7 8

运行示例代码

shift_right

在这里插入图片描述

在这里插入图片描述

shuffle

在这里插入图片描述
cppreference

#include <algorithm>
#include <random>
// 32 bit mersenne twister engine
auto const seed = std::random_device{}();
auto reng = std::mt19937{seed};
std::vector<int> v {0,1,2,3,4,5,6,7,8};
shuffle(begin(v)+2, begin(v)+7, reng);  
for (int x : v) { cout << x <<' '; }  // 0 1 … 7 8

运行示例程序
在这里插入图片描述

排序

sort

在这里插入图片描述
用于比较元素的自定义函数(对象)可以作为第三个参数传递。
cppreference

std::vector<int> v {8,9,3,1,2,3,5,4,7,6};
// sort subrange (as shown in image):
sort(begin(v)+2, begin(v)+8);
for (int x : v) { cout << x <<' '; }  // 8 9 1 2 3 3 4 5 7 6
// sort entire vector:
sort(begin(v), end(v));
for (int x : v) { cout << x <<' '; }  // 1 2 3 3 4 5 6 7 8 9
// sort vector in descending order:
sort(begin(v), end(v), std::greater<>{});
for (int x : v) { cout << x <<' '; }  // 9 8 7 6 5 4 3 3 2 1

运行示例代码
在这里插入图片描述
cppreference

stable_sort

在这里插入图片描述
stable ⇒ a 在 A 之前(而且 E 在 e 之前),尽管它们在不区分大小写的比较中是等价的。
默认情况下,使用运算符 < 比较元素; 用于比较元素的自定义函数(对象)可以作为第三个参数传递。
cppreference

#include <cctype>  // std::tolower
auto compare_case_insensitive = [](char x, char y) {
  return std::tolower(x) < std::tolower(y); };
std::string s = "gbaEAfec";
stable_sort(begin(s)+1, begin(s)+7, compare_case_insensitive);
cout << s;  // gaAbEefc

运行示例代码
在这里插入图片描述
cppreference

partial_sort / partial_sort_copy

在这里插入图片描述
默认情况下,使用运算符 < 比较元素; 用于比较元素的自定义函数(对象)可以作为第4个参数传递。
cppreference

std::vector<int> v {7,4,6,2,3,5,1,9};
// sort 4 smallest elements:
auto const nth = begin(v) + 4;
partial_sort(begin(v), nth, end(v));
for (int x : v) { cout << x <<' '; }  // 1 2 3 4 7 6 5 9

在这里插入图片描述
cppreference

在这里插入图片描述
默认情况下,使用运算符 < 比较元素; 用于比较元素的自定义函数(对象)可以作为第5个参数传递。
cppreference

std::vector<int> in {6,2,3,5,1};
// get sorted copy of 3 smallest elements:
int const n = 3;
std::vector<int> out; 
out.resize(n);
partial_sort_copy(begin(in), end(in), begin(out), end(out));
for (int x : out) { cout << x <<' '; }  // 1 2 3
// if output is larger than input:
out.resize(100);
auto const e = partial_sort_copy(begin(in), end(in), begin(out), end(out));
out.erase(e, end(out));  // shrink to fit
for (int x : out) { cout << x <<' '; }  // 1 2 3 5 6

运行示例代码
在这里插入图片描述
cppreference

nth_element

在这里插入图片描述
默认情况下,使用运算符 < 比较元素; 用于比较元素的自定义函数(对象)可以作为第4个参数传递。
cppreference

std::vector<int> v {4,2,5,6,3,7,1};
// get 5th element in sorted order
int const n = 4;
auto nth = begin(v) + n;
nth_element(begin(v), nth, end(v));
cout << *nth;  // 5

运行示例代码
在这里插入图片描述
cppreference

is_sorted

在这里插入图片描述
默认使用运算符 < 比较元素; 用于比较元素的自定义函数(对象)可以作为第3个参数传递。
cppreference

std::vector<int> v {2,3,4,5,6,1,0};
// test subrange (as shown in image):
cout << is_sorted(begin(v), begin(v)+5);  // true
// test entire vector:
cout << is_sorted(begin(v), end(v));  // false

运行示例代码
在这里插入图片描述
cppreference

is_sorted_until

在这里插入图片描述
默认使用运算符 < 比较元素; 用于比较元素的自定义函数(对象)可以作为第3个参数传递。
cppreference

std::vector<int> v {2,3,4,5,4,2,0,7,8};
// test from 1st to 7th (as shown in image):
auto i = is_sorted_until(begin(v), begin(v)+7);
// print sorted subrange
auto const print = [](int x){ cout << x << ' '; };
std::for_each(begin(v), i, print);  // 2 3 4 5

运行示例代码
在这里插入图片描述
cppreference

std::vector<int> v {2,3,4,5,4,2,0};
auto const i = std::ranges::is_sorted_until(v);
// print sorted subrange
auto const print = [](int x){ cout << x << ' '; };
std::for_each(begin(v), i, print);  // 2 3 4 5

运行示例代码

分区

partition / partition_copy

在这里插入图片描述
请注意,结果分区内元素的相对顺序不必与原序列中的顺序相同。
cppreference

auto const is_odd = [](int x) { return (x & 1); };
std::vector<int> v {3,4,6,5,7,8,0};
auto i = partition(begin(v), end(v), is_odd);
auto const print = [](int x){ cout << x << ' '; };
// print 1st subrange
std::for_each(begin(v), i, print);  // 3 7 5
// print 2nd subrange
std::for_each(i, end(v), print);  // 6 4 8 0

运行示例代码
在这里插入图片描述
cppreference
在这里插入图片描述
cppreference

auto const is_odd = [](int x) { return (x & 1); };
std::vector<int> in {3,4,6,5,0};
// ensure each output could hold all elements:
std::vector<int> out1; out1.resize(in.size());
std::vector<int> out2; out2.resize(in.size());
auto ends = partition_copy(begin(in), end(in), begin(out1), begin(out2), is_odd);
// resize partitions to fit content
out1.erase(ends.first,  end(out1));
out2.erase(ends.second, end(out2));
// print partitions
for (int x : out1) { cout << x << ' '; }  // 3 5
for (int x : out2) { cout << x << ' '; }  // 4 6 0

运行示例代码
在这里插入图片描述
cppreference

stable_partition

在这里插入图片描述
cppreference

auto const is_odd = [](int x) { return (x & 1); };
std::vector<int> v {3,4,6,5,7,8,0};
auto i = stable_partition(begin(v), end(v), is_odd);
auto const print = [](int x){ cout << x << ' '; };
// print 1st subrange
std::for_each(begin(v), i, print);  // 3 5 7
// print 2nd subrange
std::for_each(i, end(v), print);  // 4 6 8 0

运行示例代码
在这里插入图片描述
cppreference

auto const is_odd = [](int x) { return (x & 1); };
std::vector<int> v {3,4,6,5,7,8,0};
auto r2 = std::ranges::stable_partition(v, is_odd);
// print 2nd subrange
for (int x : r2) { cout << x << ' '; }  // 4 6 8 0

运行示例代码

is_partitioned

在这里插入图片描述
cppreference

auto const is_odd = [](int x) { return (x & 1); };
std::vector<int> v {3,7,5,6,4,8,0};
cout << is_partitioned(begin(v), end(v), is_odd);  // true

运行示例代码

在这里插入图片描述
cppreference

partition_point

在这里插入图片描述
在一个划分的输入范围内执行二分查找,以找到第一个使得 f 为 false 的元素。
cppreference

auto const is_odd = [](int x) { return (x & 1); };
std::vector<int> v {3,7,5,6,4,8,0};
auto i = partition_point(begin(v), end(v), is_odd);
auto const print = [](int x){ cout << x << ' '; };
// print 1st subrange
std::for_each(begin(v), i, print);  // 3 7 5
// print 2nd subrange
std::for_each(i, end(v), print);  // 6 4 8 0

运行示例代码
在这里插入图片描述
cppreference

排列

prev_permutation / next_permutation

在这里插入图片描述
在这里插入图片描述
cppreference
在这里插入图片描述
运行示例代码

在这里插入图片描述
在这里插入图片描述
cppreference

is_permutation

在这里插入图片描述
cppreference

std::vector<int> v1 {1,2,3,4};
std::vector<int> v2 {4,2,1,3};
std::vector<int> v3 {5,0,1,2};
cout << is_permutation(begin(v1), end(v1), begin(v2));  // true
cout << is_permutation(begin(v1), end(v1), begin(v3));  // false

运行示例代码

在这里插入图片描述
cppreference

相关内容

视频:reverse, rotate by:Conor Hoekstra
视频:sort, stable_sort by Conor Hoekstra
视频:partition, stable_partition and more by Conor Hoekstra
视频:next_permutation, prev_permutation by Conor Hoekstra
标准算法概述
C++标准库算法介绍
标准序列容器(vector、deque、list、…)
标准关联容器(map、set、…)
标准序列视图
cppreference:算法库
cppreference:容器库
视频:什么是 C++ 标准库?
视频:一小时内掌握 105 个 STL 算法 (Jonathan Boccara,2018)
C++ 之旅:容器和算法
算法概述表:
在这里插入图片描述
附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值