【发布时间】:2016-06-19 10:01:25
【问题描述】:
我有一个集合向量,我想删除向量中其他集合的子集的所有集合。示例:
a = {0, 3, 5}
b = {0, 5}
c = {0, 2, 3}
在这种情况下,我想删除 b,因为它是 a 的子集。我可以使用“哑” n² 算法。
遗憾的是,让它与借用检查器一起工作非常棘手。我想出的最好的是(Playground):
let mut v: Vec<HashSet<u8>> = vec![];
let mut to_delete = Vec::new();
for (i, set_a) in v.iter().enumerate().rev() {
for set_b in &v[..i] {
if set_a.is_subset(&set_b) {
to_delete.push(i);
break;
}
}
}
for i in to_delete {
v.swap_remove(i);
}
(注意:上面的代码是不正确的!更多细节见cmets)
我看到了一些缺点:
- 我需要一个带有额外分配的额外向量
- 也许有比经常致电
swap_remove更有效的方法 - 如果我需要保持秩序,我不能使用
swap_remove,但必须使用remove,这很慢
有没有更好的方法来做到这一点?我不只是询问我的用例,而是询问标题中描述的一般情况。
【问题讨论】:
-
这个算法不正确;它只删除向量中 earlier 集合的子集。示例:play.rust-lang.org/…
-
注意:保持顺序并避免重新分配可以通过构建临时(并按顺序推送)来实现,然后将其与原始交换。但目前尚不清楚临界点是什么。
-
这里是否需要保留订单?如果不是,我会先按大小对向量进行排序,这样您就可以避免双向检查子集(并删除正确的)。
-
@ChrisEmerson 谢谢!我不会在问题中修复我的代码,而是添加一条不正确的注释。但是修复它的好主意:)
标签: rust borrow-checker