在 Rust 中,a 的排序方法Vec
总是从小到大排列元素。从大到小排序的通用方法是什么?
如果你有一个数字向量,你可以提供一个密钥提取函数,像这样“反转”数字:
let mut numbers: Vec<u32> = vec![100_000, 3, 6, 2];
numbers.sort_by_key(|n| std::u32::MAX - n);
Run Code Online (Sandbox Code Playgroud)
但这不是很清楚,并且将该方法扩展到其他类型(如字符串)并不简单。
nnn*_*mmm 59
至少有三种方法可以做到。
vec.sort_by(|a, b| b.cmp(a))
Run Code Online (Sandbox Code Playgroud)
这会切换元素比较的顺序,以便较小的元素在排序函数中显得较大,反之亦然。
use std::cmp::Reverse;
vec.sort_by_key(|w| Reverse(*w));
Run Code Online (Sandbox Code Playgroud)
Reverse
是一个通用包装器,它的Ord
实例与包装类型的顺序相反。
如果您尝试Reverse
通过删除返回包含引用的*
,则会导致生命周期问题,这与直接在内部返回引用时相同sort_by_key
(另请参阅此问题)。因此,此代码片段只能与键为Copy
类型的向量一起使用。
vec.sort();
vec.reverse();
Run Code Online (Sandbox Code Playgroud)
它最初以错误的顺序排序,然后反转所有元素。
我用criterion
长度 100_000 对这三种方法进行了基准测试Vec<u64>
。计时结果按上述顺序列出。左边和右边的值分别显示了置信区间的下限和上限,中间的值是criterion
的最佳估计值。
性能相当,虽然翻转比较函数似乎有点慢:
Sorting/sort_1 time: [6.2189 ms 6.2539 ms 6.2936 ms]
Sorting/sort_2 time: [6.1828 ms 6.1848 ms 6.1870 ms]
Sorting/sort_3 time: [6.2090 ms 6.2112 ms 6.2138 ms]
Run Code Online (Sandbox Code Playgroud)
要重现,请将以下文件另存为benches/sort.rs
和Cargo.toml
,然后运行cargo bench
. 那里有一个额外的基准测试,它检查与排序相比,克隆向量的成本是否无关紧要,它只需要几微秒。
vec.sort_by(|a, b| b.cmp(a))
Run Code Online (Sandbox Code Playgroud)
[package]
name = "sorting_bench"
version = "0.1.0"
authors = ["nnnmmm"]
edition = "2018"
[[bench]]
name = "sort"
harness = false
[dev-dependencies]
criterion = "0.3"
rand = "0.7.3"
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8670 次 |
最近记录: |