如何检查切片中是否有重复项?

Fre*_*ios 3 rust

是否有本地方法来检查切片是否有重复?现在,我用这个:

fn has_dup<T: PartialEq>(slice: &[T]) -> bool {
    for i in 1..slice.len() {
        if slice[i..].contains(&slice[i - 1]) {
            return true;
        }
    }
    false
}

fn main() {
    assert_eq!(has_dup(&[1, 2, 3, 2, 5, 6]), true);
    assert_eq!(has_dup(&[1, 2, 3, 4, 5, 6]), false);
}
Run Code Online (Sandbox Code Playgroud)

但对于这种基本操作,我不喜欢使用手工制作的代码.

如果在标准库中没有可用的功能,那么它是一种优化我的代码的方法吗?我知道对切片进行索引并不是最优化的方式(for i in slice {}vs for i in 0..slice.len() { slice[i] }).

E_n*_*ate 8

就算法复杂性而言,通常最好跟踪索引中的唯一值.如果你可以用Hash和检查相等Eq,你可以试试这个效用函数:

fn has_unique_elements<T>(iter: T) -> bool
where
    T: IntoIterator,
    T::Item: Eq + Hash,
{
    let mut uniq = HashSet::new();
    iter.into_iter().all(move |x| uniq.insert(x))
}

assert!(!has_unique_elements(vec![10, 20, 30, 10, 50]));
assert!(has_unique_elements(vec![10, 20, 30, 40, 50]));
assert!(has_unique_elements(Vec::<u8>::new()));
Run Code Online (Sandbox Code Playgroud)

操场

同样,如果您的元素没有实现Hash但是实现Ord,则可以使用BTreeSet(Playground).

  • 没有打破鸡蛋就不能做煎蛋.:P快速查找需要哈希函数或总顺序关系.我不确定是否可以避免复制以前提取的项目. (3认同)
  • @Boiethios:注意`Clone`,如果你在`&Vec`上调用这个方法,那么你得到一个*references*的迭代器,它默认是可克隆的.我认为通过价值来称呼它是非常罕见的. (2认同)

oli*_*obk 6

索引并没有减少优化,它只是在存在迭代器解决方案时不是惯用。没有迭代器解决方案,因此您的代码已经是最佳解决方案。

如果你想走更实用的道路,你可以写

(1..slice.len()).any(|i| slice[i..].contains(&slice[i - 1]))
Run Code Online (Sandbox Code Playgroud)