Rust数组排序检查库is_sorted的使用:高效检测数组或迭代器是否已排序的Rust工具

Rust数组排序检查库is_sorted的使用:高效检测数组或迭代器是否已排序的Rust工具

is_sorted是一个扩展了Iterator特性的Rust库,提供了is_sortedis_sorted_byis_sorted_by_key方法,可以在O(N)时间和O(1)空间内检查迭代器元素是否按某种顺序排序。

特性

该库展示了编写Rust组件时的一些中级技巧:

  • 扩展Iterator添加自定义算法
  • 使用特化(specialization)为特定类型比较对提供更高效的实现
  • 使用stdsimdtarget_featurecfg_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库在检测时会:

  1. 尽早返回 - 一旦发现不符合排序条件的元素就立即返回
  2. 避免不必要的比较 - 不会对整个数组进行完全排序检查
  3. 支持短路评估 - 对于大型数据集合更高效

对于已排序的数据,最坏情况下需要遍历全部元素;对于未排序的数据,通常能在早期就返回结果。

注意事项

  1. 对于包含NaN的浮点数数组,总是返回false
  2. 空数组或单元素数组总是被认为是已排序的
  3. 对于自定义比较函数,必须确保比较关系是传递性的

完整示例代码

// 完整示例演示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());
}
回到顶部