我想迭代一個數組/矢量一次,並在路上修改多個元素,因爲這是最優化的解決方案。我不想一次又一次地掃描它,只是因爲魯斯對借款感到不滿。如何迭代一次矢量,並在此過程中插入/刪除/修改多個元素?
我在一個已排序的向量中存儲了一個表示爲[start;stop]
的區間列表,我想添加一個新區間。它可能會重疊,所以我想刪除所有不再需要的元素。我想一口氣做到這一切。算法看起來像這樣(我削減了一些部分):
use std::cmp::{min, max};
#[derive(Debug, PartialEq, Clone, Copy)]
struct Interval {
start: usize,
stop: usize,
}
impl Interval {
fn new(start: usize, stop: usize) -> Interval {
Interval {
start: start,
stop: stop,
}
}
pub fn starts_before_disjoint(&self, other: &Interval) -> bool {
self.start < other.start && self.stop < other.start
}
pub fn starts_before_non_disjoint(&self, other: &Interval) -> bool {
self.start <= other.start && self.stop >= other.start
}
pub fn starts_after(&self, other: &Interval) -> bool {
self.start > other.start
}
pub fn starts_after_disjoint(&self, other: &Interval) -> bool {
self.start > other.stop
}
pub fn starts_after_nondisjoint(&self, other: &Interval) -> bool {
self.start > other.start && self.start <= other.stop
}
pub fn disjoint(&self, other: &Interval) -> bool {
self.starts_before_disjoint(other)
}
pub fn adjacent(&self, other: &Interval) -> bool {
self.start == other.stop + 1 || self.stop == other.start - 1
}
pub fn union(&self, other: &Interval) -> Interval {
Interval::new(min(self.start, other.start), max(self.stop, other.stop))
}
pub fn intersection(&self, other: &Interval) -> Interval {
Interval::new(max(self.start, other.start), min(self.stop, other.stop))
}
}
fn main() {
//making vectors
let mut vec = vec![
Interval::new(1, 1),
Interval::new(2, 3),
Interval::new(6, 7),
];
let addition = Interval::new(2, 5); // <- this will take over interval @ 2 and will be adjacent to 3, so we have to merge
let (mut i, len) = (0, vec.len());
while i < len {
let r = &mut vec[i];
if *r == addition {
return; //nothing to do, just a duplicate
}
if addition.adjacent(r) || !addition.disjoint(r) {
//if they are next to each other or overlapping
//lets merge
let mut bigger = addition.union(r);
*r = bigger;
//now lets check what else we can merge
while i < len - 1 {
i += 1;
let next = &vec[i + 1];
if !bigger.adjacent(next) && bigger.disjoint(next) {
//nothing to merge
break;
}
vec.remove(i); //<- FAIL another mutable borrow
i -= 1; //lets go back
vec[i] = bigger.union(next); //<- FAIL and yet another borrow
}
return;
}
if addition.starts_before_disjoint(r) {
vec.insert(i - 1, addition); // <- FAIL since another refence already borrowed @ let r = &mut vec[i]
}
i += 1;
}
}
由於借貸規則,它在一些地方失敗。有沒有辦法要麼
- 迭代器做在一個四處借款
這樣做是爲了將'vec'變成一個明確的目標嗎?這似乎是通過製作一個新的「Vec」並添加項目來實現,而不是試圖更改原始的「vec」會顯着簡化。 – loganfsmyth
@loganfsmyth可能是一個小矢量的選項,小數據結構 – Windys