我一直在尝试优化代码中的某一部分,但我遇到了一个需要社区智慧的地方。我实际上想要合并列表中的两个元素,而不移动列表中的元素(通过两个删除和一个插入),因为在Rust中这样做会花费O(n)的时间。请查看以下代码,它捕捉了我的问题的本质:
use std::cell::RefCell;
use std::rc::Rc;
use std::collections::BinaryHeap;
#[derive(PartialOrd, Ord, PartialEq, Eq)]
pub struct Num {
pub num: usize
}
impl Num {
pub fn new(num: usize) -> Num {
Num {
num
}
}
}
fn main() {
let mut a = vec![];
for i in 0..10 {
a.push(Rc::new(RefCell::new(Num::new(i))));
}
let mut b = BinaryHeap::with_capacity(a.len());
for i in 0..a.len() - 1 {
b.push((i, Rc::clone(&a[i]), Rc::clone(&a[i + 1])));
}
drop(a);
while !b.is_empty() {
let c = b.pop().unwrap();
let first = c.1;
let next = c.2;
println!("c: c.0: {}", c.0);
println!("c: first.num before: {}", RefCell::borrow(&first).num);
println!("c: next.num before: {}", RefCell::borrow(&next).num);
// Here I want to replace the two structs referenced in first and next
// with a single new struct that first and next both point to.
// e.g. first -> new_num <- next
println!("c: first.num after: {}", RefCell::borrow(&first).num);
println!("c: next.num after: {}", RefCell::borrow(&next).num);
assert_eq!(RefCell::borrow(&first).num, RefCell::borrow(&next).num);
}
}
我希望能够将列表中的两个元素合并为一个伪元素,其中前两个“元素”实际上只是指向同一个新元素的指针。但是,我正在努力寻找一种在不在列表中复制内存或结构的情况下完成此操作的方法。
VecDeque
。 - Peter HallVec
和BinaryHeap
?当你说要编辑列表中的元素时,是指Vec
还是BinaryHeap
? - michalsrbwhile
循环中,first
和next
不再是任何列表的成员,因为a
已经被删除并且你将它们从b
中弹出了。所以...如果你想要的话,你可以重新分配它们(first = new_num; next = new_num;
),测试就会通过。但是听起来你想对一些其他数据结构产生副作用,而这些数据结构没有显示出来?或者你想对堆的其他元素产生副作用?我不明白。 - trent