You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中BTreeMap嵌套HashSet邻接表删节点遇借用检查报错如何解决

错误原因
  • 直接调用adj.get()返回的是&HashSet<..>不可变引用,HashSet::remove需要修改集合内容,必须拿到可变引用才能调用,这是报错直接提示的问题。
  • 隐藏的借用冲突问题:你先持有adj的不可变引用读取当前石头的邻居集合,遍历过程中又要获取adj的可变引用修改邻居的邻接表,违反Rust借用规则:同一容器不能同时存在活跃的可变借用和不可变借用。
修复方案

你不需要用到iter_mut,只要先把当前石头的邻居列表复制出来,提前释放对adj的不可变借用,再遍历复制的列表修改邻接表即可,修改后的代码如下:

// 先复制当前顶点的所有邻居,释放对adj的不可变借用
let stone_neighbours: Vec<_> = adj.get(&(top.1, top.2)).unwrap().iter().copied().collect();
// 遍历复制的邻居列表,逐个移除当前顶点的记录
for neighbour in stone_neighbours {
    // 用get_mut获取邻居邻接表的可变引用
    adj.get_mut(&neighbour).unwrap().remove(&(top.1, top.2));
}
// 可选:把已经移除的顶点本身从邻接表中删掉,避免后续误访问
adj.remove(&(top.1, top.2));

额外优化提示

  1. 你构建邻接表的代码里,两次调用entry(..).or_insert(..).insert(..)逻辑完全重复,第二遍是无效操作,可以删掉一行。
  2. 当前优先队列的实现存在逻辑问题:你修改了邻居的边数之后,堆里存储的还是旧的边数数值,弹出的元素可能是过时的,你可以增加延迟删除的逻辑,弹出元素时先校验边数和当前邻接表中存储的边数是否一致,不一致就跳过这个元素。

内容的提问来源于stack exchange,提问作者user2346536

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 06:39:03