如何检查切片是否已排序?

Nic*_*ick 8 sorting iterator slice rust

如何检查切片是否已排序?

假设一个接受切片的函数i32,是否有一种惯用的Rust检查切片是否已排序的方法?

fn is_sorted(data: &[i32]) -> bool {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

是否有可能推广上述方法以便接受迭代器?

fn is_sorted<I>(iter: I)
where 
    I: Iterator, 
    I::Item: Ord,
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 10

我会抓住成对的元素并断言它们都在升序(或降序,取决于你的"排序"的顺序)顺序:

fn is_sorted<T>(data: &[T]) -> bool
where
    T: Ord,
{
    data.windows(2).all(|w| w[0] <= w[1])
}

fn main() {
    assert!(is_sorted::<u8>(&[]));
    assert!(is_sorted(&[1]));
    assert!(is_sorted(&[1, 2, 3]));
    assert!(is_sorted(&[1, 1, 1]));
    assert!(!is_sorted(&[1, 3, 2]));
    assert!(!is_sorted(&[3, 2, 1]));
}
Run Code Online (Sandbox Code Playgroud)

通用迭代器同上:

extern crate itertools; // 0.7.8

use itertools::Itertools;

fn is_sorted<I>(data: I) -> bool
where
    I: IntoIterator,
    I::Item: Ord + Clone,
{
    data.into_iter().tuple_windows().all(|(a, b)| a <= b)
}

fn main() {
    assert!(is_sorted(&[] as &[u8]));
    assert!(is_sorted(&[1]));
    assert!(is_sorted(&[1, 2, 3]));
    assert!(is_sorted(&[1, 1, 1]));
    assert!(!is_sorted(&[1, 3, 2]));
    assert!(!is_sorted(&[3, 2, 1]));
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • @Shepmaster"*你有没有想过检查一下是否有东西被排序?*" - 实际上,经常:**单元测试和前/后条件检查**.[我在这里写了几个关于这个的话](https://github.com/LukasKalbertodt/rfcs/blob/rfc-add-is-sorted/text/0000-is-sorted.md#motivation); - ) (5认同)

orl*_*rlp 5

不需要具有Clone迭代器is_sorted实现。这是不依赖Rust的实现is_sorted

fn is_sorted<I>(data: I) -> bool
where
    I: IntoIterator,
    I::Item: Ord,
{
    let mut it = data.into_iter();
    match it.next() {
        None => true,
        Some(first) => it.scan(first, |state, next| {
            let cmp = *state <= next;
            *state = next;
            Some(cmp)
        }).all(|b| b),
    }
}
Run Code Online (Sandbox Code Playgroud)