rust 递归函数中的可变引用

jc3wubiy  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(161)

我有一个字符栈向量叫做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中不可能解决这种问题?

wj8zmpe1

wj8zmpe11#

你写你想做的事情不容易用栈来完成。
我将给予你一个提示,让你避免这个问题,因为我假设你已经解决了2022年代码挑战第5天的第1部分:p
在第1部分中,通过pop获取一个元素,并通过push将其放到另一个堆栈中,然后重复num次,非常简单。
现在对于第2部分,您需要反转弹出元素的顺序。那么为什么不使用 another stack来跟踪它们呢?要在保持顺序的同时将元素从一个堆栈A移动到堆栈B,您可以首先使用第1部分中的简单“pop-push”算法将它们从堆栈A移动到堆栈C,然后使用简单的pop-push算法将它们从堆栈C再次移动到堆栈B:

Stack A: 1 2 3 4
Stack B: 
Stack C:

do the pop-push 4 times

Stack A:
Stack B:
Stack C: 4 3 2 1

do the pop-push 4 times

Stack A:
Stack B: 1 2 3 4
Stack C

这就避免了“双可变引用”的问题,因为您不需要让两个可变的VecDequeue引用同时活动。
编辑:题外话:在处理递归和遇到问题时,通常可以通过 * 显式地 * 创建和管理堆栈来避免这些问题。

相关问题