我有一个字符栈向量叫做crates,这些栈是用VecDeque<char>
表示的,因此向量是Vec<VecDeque<char>>
,这个数据结构不是一个真正的栈,但是我想把它当作一个栈来使用,从后往前迭代,然后在后面添加元素。
我想把一个栈的最后k个字符移到另一个栈,但我想保持它们的顺序。
示例:
stack_a = [ 1 <- 2 <- 3 <- 4 ]
stack_b = [ 5 <- 6 ]
# movement from a to b with k=3
stack_b = [ 5 <- 6 <- 2 <- 3 <- 4 ]
你可以注意到,这不是一件容易的事情,如果你有权利改变元素添加到另一个堆栈的顺序,这将是很容易的,因为你可以重复k次:push(stack_b, pop(stack_a))
但是这里我们需要对调用重新排序,弹出k次,将k个值保存在内存中,然后推送它们,这可以很容易地用递归函数来表达。
下面是我的代码:
// I'm extracting my stack ids from a regex capture
let source_id = usize::from_str(&cap[2]).unwrap() - 1;
let target_id = usize::from_str(&cap[3]).unwrap() - 1;
// My simple function
fn move_crates_simultaneously(
amount: usize,
source: Rev<Iter<char>>,
target: &mut VecDeque<char>,
) {
if amount == 0 {
return;
}
let value = source.next();
move_crates_simultaneously(amount - 1, source, target);
target.push_back(*(value.unwrap()));
}
// My function call
move_crates_simultaneously(
usize::from_str(&cap[1]).unwrap(),
crates[source_id].iter().rev(),
&crates[target_id],
);
但有一个问题:&crates[target_id]
是&VecDeque<char, Global>
,而函数需要一个&mut VecDeque<char, Global>
。从我的理解来看,似乎不可能找到一个解决方案,因为现在有一种方法让编译器知道我的源和目标不是同一个堆栈,从而让我为目标创建我的可变ref。这是否意味着在Rust中不可能解决这种问题?
1条答案
按热度按时间wj8zmpe11#
你写你想做的事情不容易用栈来完成。
我将给予你一个提示,让你避免这个问题,因为我假设你已经解决了2022年代码挑战第5天的第1部分:p
在第1部分中,通过
pop
获取一个元素,并通过push
将其放到另一个堆栈中,然后重复num
次,非常简单。现在对于第2部分,您需要反转弹出元素的顺序。那么为什么不使用 another stack来跟踪它们呢?要在保持顺序的同时将元素从一个堆栈A移动到堆栈B,您可以首先使用第1部分中的简单“pop-push”算法将它们从堆栈A移动到堆栈C,然后使用简单的pop-push算法将它们从堆栈C再次移动到堆栈B:
这就避免了“双可变引用”的问题,因为您不需要让两个可变的VecDequeue引用同时活动。
编辑:题外话:在处理递归和遇到问题时,通常可以通过 * 显式地 * 创建和管理堆栈来避免这些问题。