【问题标题】:rust combine similar values in a sequence [duplicate]rust 按顺序组合相似的值[重复]
【发布时间】:2021-08-23 15:08:59
【问题描述】:

在 rust 中,给定一些序列(数组、向量等),什么是组合所有相同值并返回具有唯一值的序列的好方法?

举一个具体的例子,给定一个数组[1, 2, 2, 3, 2],修改返回的数组(或创建一个新的数组或向量),使每个u32值只包含一次,即它变成[1, 2, 3]
稍后,我想对结果进行迭代。

在这种情况下,“好方法”意味着不太复杂,易于理解。该解决方案可以使用std::collections

【问题讨论】:

  • 我不知道“sequence”是否是好的生锈措辞。我从 Python 中借用了这句话。
  • 需要保留原序列的顺序吗?如果没有,您是否考虑过使用HashSet
  • "需要保留原序列的顺序吗?"是的。

标签: rust


【解决方案1】:

简单:重复数据删除!正如rust doc for Vec::dedup 所说:

根据 PartialEq trait 实现移除向量中连续重复的元素。

如果向量已排序,则会删除所有重复项。

let mut vec = vec![1, 2, 2, 3, 2];

vec.dedup();

assert_eq!(vec, [1, 2, 3, 2]);

正如文档所说,如果已排序,则会删除所有重复项。另见Vec::sort

【讨论】:

  • @JamesThomasMoon 的注意事项 - sort 的文档明确表示它是稳定的,因此您的订单使用我上面引用的文档中的方法保留。并注意@Brian - 感谢您通过编辑进行格式清理。我喜欢。
【解决方案2】:

如果您不关心订购,您可以使用HashSet

use std::collections::HashSet;

fn main() {
    let data = vec![1, 2, 2, 3, 2];
    let res: Vec<u32> = data
        .iter()
        .copied()
        .collect::<HashSet<_>>()
        .into_iter()
        .collect();
    println!("{:?}", res);
}

Playground

Idea 又来自 Vec -> HashSet -> Vec。

【讨论】:

  • 机会回到 Vec 甚至不需要 - 只需保留 HashSet
  • 请注意,这种方法的平均运行时间为 O(n),而 sort(); dedup(); 方法的平均运行时间为 O(n log n)。
  • 去重是 O(n),但排序是 O(n log n)。实现很复杂,因为比较函数(或删除元素)可能会出现恐慌,因此很难确保向量始终处于定义状态。
  • @Stargateur 哈希函数的运行时间为 O(1)。构建哈希集时重新分配的摊销成本也是 O(1)。这些都没有被“忽略”——它们只是不会以任何方式改变算法的摊销运行时间。老实说,我不确定您对我所说的话到底有什么“奇怪”,但仍然相信我所说的一切都是准确的。我可以使用 Ω(n) 而不是 O(n),但我通常觉得在英国键盘上打字太费力了。
  • @SvenMarnach 我想说的是,hashmap 不是魔术,我厌倦了人们继续传播有关它的缺失信息。至少 std 清楚地说明它doc.rust-lang.org/std/collections/#maps。一个插入是O(1)~*,但插入n 个对象肯定会触发重新分配等等,因此声称它只是O(n) 在实践中是完全错误的。同样,这不考虑哈希函数。复杂性并不容易,hashmap 也不是魔法。我更希望看到基准来查看具有不同参数的不同实现,而不是在这里使用 O 表示法。
猜你喜欢
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 2016-06-11
  • 2012-10-24
  • 1970-01-01
相关资源
最近更新 更多