我正在学习Rust的乐趣,当编写一个函数以返回第n个素数时,我意识到我的解决方案不雅且浪费。
当我只想遍历尚未验证的部分时,我遍历整个可能的素数。使用keep()函数时,有什么方法可以做到这一点?
我的主要问题是,我相信keep()函数是为Vec实现的,而不是为slice实现的。我尝试研究切片文档以获取进一步的想法,但找不到任何内容。
这是代码。
let mut prime_list: Vec<u32> = (2..n).collect();
let mut i: usize = 0;
while i < prime_list.len() {
let prime: u32 = prime_list[i];
prime_list.retain(
|x| x <= &prime || x % &prime != 0);
i += 1;
}
所以问题出在函数调用中
prime_list.retain(
|x| x <= &prime || x % &prime != 0);
每次我进入此循环时,都不需要遍历列表中的每个元素,因为我知道我已经对“ i”之前的元素进行了验证。
但是keep()函数需要遍历整个容器,因此我在其中添加了一个检查(x <=&prime || ...)以忽略当前容器之前的所有元素。
我想做的就是优雅地从位置“ i”的元素开始,然后遍历列表中的删除元素。
我知道我可以用不太优雅的while或for循环来做到这一点,但我希望有一种Rust方式来优雅地做到这一点。
感谢您的帮助!
编辑:这是一个可能的拆分和filter()解决方案,感觉比我想的还要模糊...如果有更好的方法使用filter()方法和迭代器,我将不胜感激朝着正确的方向。
// inside the while loop
let prime: u32 = prime_list[i];
let (left, right) = prime_list.split_at(i);
prime_list = left.iter()
.chain(
right.iter()
.filter(|x| *x == &prime || *x % &prime != 0))
.map(|&x| x)
.collect();
i += 1;
答案 0 :(得分:0)
这并不能完全解决您想要的东西,但是我想我会做出一些“生锈”的尝试,因为它已经写了一段时间的锈。
// collectionView.bounces = false
// collectionView.isScrollEnabled = false
我将质数存储在一个单独的向量中,因为我想随其添加。与在迭代过程中尝试使用保留从向量中删除某些元素相比,这确实感觉要优雅得多。
如果您真的想花哨的话,可以使用let mut primes = Vec::new();
for e in 2..100 {
if primes.iter().all(|p| e % p != 0) {
primes.push(e);
}
}
println!("{:?}", primes);
进行一些优化,然后在获得第n个素数后停止。
with_capacity