作者:lvyanbo | 来源:互联网 | 2023-02-03 13:56
我在kata期间遇到了这个问题.我更具可读性的实现如下:
use std::vec::Vec;
fn repeat_even(v: Vec) -> Vec {
v.into_iter().flat_map(|x| match x % 2 { 0 => vec![x, x], _ => vec![x] }).collect()
}
fn main() {
let v = vec![1, 2, 3, 4, 6];
assert_eq!(repeat_even(v), vec![1, 2, 2, 3, 4, 4, 6, 6]);
}
我有两个问题:
是否有必要创造另一个Vec
?可以使用相同的Vec
,即在迭代时修改它吗?
我认为,我的解决方案效率低下:我分配了很多向量,而且我无法保证这将得到优化.是否有更好的解决方案:可读性和分配更少?
ljedrz..
5
你可以在同一个向量中完成它,但是每次遇到偶数时都需要移动向量的其余部分(在加倍数之后),这是低效的.使用新的向量和简单的循环做它会更好:
fn main() {
let v = vec![1, 2, 3, 4, 6];
let mut v2 = Vec::with_capacity(v.len() + v.iter().filter(|&n| n % 2 == 0).count());
for n in v {
v2.push(n);
if n % 2 == 0 { v2.push(n) }
}
assert_eq!(v2, vec![1, 2, 2, 3, 4, 4, 6, 6]);
}
此解决方案仅分配内存一次,具有保存所有数字所需的确切空间,包括双倍均衡.
1> ljedrz..:
你可以在同一个向量中完成它,但是每次遇到偶数时都需要移动向量的其余部分(在加倍数之后),这是低效的.使用新的向量和简单的循环做它会更好:
fn main() {
let v = vec![1, 2, 3, 4, 6];
let mut v2 = Vec::with_capacity(v.len() + v.iter().filter(|&n| n % 2 == 0).count());
for n in v {
v2.push(n);
if n % 2 == 0 { v2.push(n) }
}
assert_eq!(v2, vec![1, 2, 2, 3, 4, 4, 6, 6]);
}
此解决方案仅分配内存一次,具有保存所有数字所需的确切空间,包括双倍均衡.