是否有一种原生方式来检查切片是否有重复?现在,我用这个:
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);
}
但对于这种基本操作,我不喜欢使用手工制作的代码。
如果在标准库中没有可用的功能,那么它是一种优化我的代码的方法吗?我知道对切片建立索引并不是最优化的方式(for i in slice {}
vs for i in 0..slice.len() { slice[i] }
)。
答案 0 :(得分: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()));
同样,如果您的元素没有实现Hash
但实施Ord
,则可以使用BTreeSet
代替Playground。
答案 1 :(得分:3)
索引的优化程度不低,在迭代器解决方案的情况下,它不是惯用的。没有迭代器解决方案,因此您的代码已经是最佳解决方案。
如果你想走更实用的道路,可以写
(1..slice.len()).any(|i| slice[i..].contains(&slice[i - 1]))