arrays - 如何在 Rust 中为 Vec<String> 编写计数器函数?

标签 arrays string rust hashmap

<分区>

函数名称: my_counter
输入: ['foo', 'bar', 'bar', 'bar', 'bar']]
输出: {'foo': 1, 'bar': 4}

注意:输出类型是HashMap,不是HashMap<&str, usize>。

这是我的实现,我认为它有一点开销。 “bar”已被转换为字符串四次,但可能不需要。

pub fn my_counter(vec: &Vec<String>) -> HashMap<String, usize> {
    let mut result: HashMap<String, usize> = HashMap::new();
    for key in vec.iter() {
        let val = result.entry(key.to_string()).or_insert(0);
        *val += 1;
    }
    result
}

有人愿意分享更好的解决方案吗?非常感谢~

最佳答案

您可以做的一件事是避免创建新的 String通过消耗(或移动)原始向量的值。像这样:

pub fn my_counter(vec: Vec<String>) -> HashMap<String, usize> {
    let mut result: HashMap<String, usize> = HashMap::new();
    for key in vec {
        let val = result.entry(key).or_insert(0);
        *val += 1;
    }
    result
}

注意更改后的函数签名:vec现在是Vec<String> , 不是 &Vec<String> .如果出于某种原因,那是 Not Acceptable ,那么您真的无法避免创建新的 StringHashMap 的值的 key 。假设 N 是矢量项的数量,M 是唯一矢量项的数量。如果您知道您将在向量中有很多重复值(也就是说,M 远小于N),理论上您只创建 M 个新的 String 或许能够逃脱惩罚秒。但是,Rust 似乎没有提供稳定 方法来直接实现这一点。如果您可以使用 Nightly,可以尝试 raw_entry_mut() .

另一种方法可能是先创建一个临时的 HashMap<&str, usize>然后将其转换为所需的“完全拥有”HashMap<String, usize> .然而,这很可能只会让事情变得更糟。这实际上取决于您拥有的 key 。使用短键和 M:N 的比率约为 0.5-1.0 是一回事,如果您使用长键且比率为 0.0001,则完全不同。

如果您对唯一键的数量有一个很好的想法,您肯定可以通过简单地创建 HashMap 来在一定程度上加快速度。与 HashMap::with_capacity(...); .使用默认哈希器的替代方案在理论上也有帮助,尽管我只尝试过 FnvHashMap甚至简称String键我无法获得任何显着的加速。

关于arrays - 如何在 Rust 中为 Vec<String> 编写计数器函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70819011/

相关文章:

javascript - 通过验证将 Angular 形式输入到数组

javascript - 我需要在单击输入框时显示我的段落。我的 p 数组如何不循环遍历我的段落变量?

php - 计算mysql结果的平均值php

rust - 当我想将所有权传递给函数时,调用采用引用的异步 Rust 函数的惯用方法

rust - 函数标记为#[no_mangle],但未导出

rust - 超性状范围内的生命周期参数

arrays - 为什么我的数组打印的是对象位置而不是值?

java - 如何在 Android 应用程序上使用 JSON 解析的 Activity 之间传递字符串?

c++ - 我的代码正确,但Leetcode平台不接受。 (之字形转换)

python - 拆分字符串而不丢失分隔符(及其计数)