Rust数组排序检查库is_sorted的使用:高效检测数组或迭代器是否已排序的Rust工具
Rust数组排序检查库is_sorted的使用:高效检测数组或迭代器是否已排序的Rust工具
is_sorted
是一个扩展了Iterator
特性的Rust库,提供了is_sorted
、is_sorted_by
和is_sorted_by_key
方法,可以在O(N)
时间和O(1)
空间内检查迭代器元素是否按某种顺序排序。
特性
该库展示了编写Rust组件时的一些中级技巧:
- 扩展
Iterator
添加自定义算法 - 使用特化(specialization)为特定类型比较对提供更高效的实现
- 使用
stdsimd
、target_feature
和cfg_target_feature
进行显式向量化 - 实现可特化的调用对象
- 支持稳定版用户同时使用大量夜间版功能
示例代码
use is_sorted::IsSorted;
fn main() {
// 检查数组是否按升序排列
let sorted_arr = [1, 2, 3, 4, 5];
assert!(sorted_arr.iter().is_sorted());
// 检查数组是否按降序排列
let descending_arr = [5, 4, 3, 2, 1];
assert!(descending_arr.iter().is_sorted_by(|a, b| a >= b));
// 使用自定义键函数检查排序
struct Item { value: i32 }
let items = [Item { value: 1 }, Item { value: 2 }, Item { value: 3 }];
assert!(items.iter().is_sorted_by_key(|x| x.value));
// 使用预定义的比较器
use is_sorted::{Increasing, Decreasing};
assert!(sorted_arr.iter().is_sorted_by(Increasing));
assert!(descending_arr.iter().is_sorted_by(Decreasing));
}
完整示例demo
use is_sorted::IsSorted;
use is_sorted::{Increasing, Decreasing};
fn main() {
// 示例1: 检查基本类型的升序排序
let nums = [1, 2, 3, 4, 5];
println!("nums is sorted: {}", nums.iter().is_sorted()); // true
// 示例2: 检查降序排序
let nums_desc = [5, 4, 3, 2, 1];
println!("nums_desc is sorted descending: {}",
nums_desc.iter().is_sorted_by(|a, b| a >= b)); // true
// 示例3: 检查浮点数排序
let floats = [1.0, 2.5, 3.7, 4.2];
println!("floats is sorted: {}", floats.iter().is_sorted()); // true
// 示例4: 使用自定义结构体和键函数
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
let people = [
Person { name: "Alice".to_string(), age: 20 },
Person { name: "Bob".to_string(), age: 25 },
Person { name: "Charlie".to_string(), age: 30 },
];
println!("people sorted by age: {}",
people.iter().is_sorted_by_key(|p| p.age)); // true
// 示例5: 使用预定义比较器
let chars = ['a', 'b', 'c', 'd'];
println!("chars sorted increasing: {}",
chars.iter().is_sorted_by(Increasing)); // true
let chars_desc = ['d', 'c', 'b', 'a'];
println!("chars sorted decreasing: {}",
chars_desc.iter().is_sorted_by(Decreasing)); // true
// 示例6: 处理未排序的情况
let unsorted = [1, 3, 2, 4];
println!("unsorted is sorted: {}", unsorted.iter().is_sorted()); // false
}
性能
该库通过显式向量化提供了显著的性能提升,在基准测试中速度提升可达1.5倍到10倍。例如:
// 基准测试示例
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[bench]
fn bench_large_sorted_array(b: &mut Bencher) {
let arr: Vec<_> = (0..1_000_000).collect();
b.iter(|| arr.iter().is_sorted());
}
}
安装
在Cargo.toml中添加:
[dependencies]
is_sorted = "0.1.1"
或者运行:
cargo add is_sorted
许可证
该项目采用以下任一许可证:
- Apache License 2.0
- MIT license
贡献
除非您明确说明,否则任何有意提交以包含在is_iterator
中的贡献,如Apache-2.0许可证所定义,都应如上所述双重许可,无需任何附加条款或条件。
1 回复
Rust数组排序检查库is_sorted的使用指南
is_sorted
是一个Rust库,用于高效检测数组或迭代器是否已排序。它提供了比手动实现更简洁、更高效的方式来检查排序状态。
基本使用方法
首先在Cargo.toml
中添加依赖:
[dependencies]
is_sorted = "0.1"
检查数组是否排序
use is_sorted::IsSorted;
fn main() {
let sorted_array = [1, 2, 3, 4, 5];
let unsorted_array = [1, 3, 2, 4, 5];
// 检查升序排序
assert!(IsSorted::is_sorted(&mut sorted_array.iter()));
assert!(!IsSorted::is_sorted(&mut unsorted_array.iter()));
// 也可以直接对数组切片使用
assert!(sorted_array.is_sorted());
assert!(!unsorted_array.is_sorted());
}
自定义排序顺序检查
use is_sorted::IsSorted;
use std::cmp::Ordering;
fn main() {
let descending = [5, 4, 3, 2, 1];
// 检查降序排序
assert!(IsSorted::is_sorted_by(&mut descending.iter(), |a, b| b.partial_cmp(a).unwrap()));
// 使用闭包简化
assert!(descending.is_sorted_by(|a, b| b.partial_cmp(a).unwrap()));
}
检查浮点数数组
use is_sorted::IsSorted;
fn main() {
let floats = [1.0, 2.5, 3.3, 4.2];
let nan_floats = [1.0, f64::NAN, 3.3];
assert!(floats.is_sorted());
assert!(!nan_floats.is_sorted()); // 包含NaN的数组不会被识别为已排序
}
高级用法
检查自定义类型的排序
use is_sorted::IsSorted;
#[derive(Debug, PartialEq, PartialOrd)]
struct Person {
age: u8,
name: String,
}
fn main() {
let people = [
Person { age: 20, name: "Alice".to_string() },
Person { age: 25, name: "Bob".to_string() },
Person { age: 30, name: "Charlie".to_string() },
];
// 按年龄检查排序
assert!(people.is_sorted_by_key(|p| p.age));
// 按名字检查排序
assert!(!people.is_sorted_by_key(|p| p.name.as_str()));
}
使用迭代器检查
use is_sorted::IsSorted;
fn main() {
let vec = vec![1, 2, 3, 4];
let iter = vec.iter();
assert!(IsSorted::is_sorted(&mut iter.clone()));
// 也可以链式调用
let is_sorted = vec.iter().is_sorted();
assert!(is_sorted);
}
性能特点
is_sorted
库在检测时会:
- 尽早返回 - 一旦发现不符合排序条件的元素就立即返回
- 避免不必要的比较 - 不会对整个数组进行完全排序检查
- 支持短路评估 - 对于大型数据集合更高效
对于已排序的数据,最坏情况下需要遍历全部元素;对于未排序的数据,通常能在早期就返回结果。
注意事项
- 对于包含NaN的浮点数数组,总是返回
false
- 空数组或单元素数组总是被认为是已排序的
- 对于自定义比较函数,必须确保比较关系是传递性的
完整示例代码
// 完整示例演示is_sorted库的所有主要功能
use is_sorted::IsSorted;
use std::cmp::Ordering;
fn main() {
// 1. 基础数组排序检查
let sorted = [1, 2, 3, 4, 5];
let unsorted = [1, 3, 2, 4, 5];
println!("基础数组检查:");
println!("sorted数组已排序: {}", sorted.is_sorted());
println!("unsorted数组已排序: {}", unsorted.is_sorted());
// 2. 自定义排序顺序
let descending = [5, 4, 3, 2, 1];
println!("\n降序数组检查:");
println!("使用is_sorted_by: {}", descending.is_sorted_by(|a, b| b.partial_cmp(a).unwrap()));
// 3. 浮点数检查
let floats = [1.0, 2.5, 3.3, 4.2];
let nan_floats = [1.0, f64::NAN, 3.3];
println!("\n浮点数数组检查:");
println!("正常浮点数组: {}", floats.is_sorted());
println!("包含NaN的数组: {}", nan_floats.is_sorted());
// 4. 自定义类型检查
#[derive(Debug, PartialEq, PartialOrd)]
struct Person {
age: u8,
name: String,
}
let people = vec![
Person { age: 20, name: "Alice".to_string() },
Person { age: 25, name: "Bob".to_string() },
Person { age: 30, name: "Charlie".to_string() },
];
println!("\n自定义类型检查:");
println!("按年龄排序: {}", people.is_sorted_by_key(|p| p.age));
println!("按名字排序: {}", people.is_sorted_by_key(|p| p.name.as_str()));
// 5. 迭代器检查
let numbers = vec![10, 20, 30, 40];
println!("\n迭代器检查:");
println!("使用IsSorted trait: {}", IsSorted::is_sorted(&mut numbers.iter()));
println!("使用链式调用: {}", numbers.iter().is_sorted());
}