【问题标题】:Can I do this with an iterator?我可以用迭代器做到这一点吗?
【发布时间】:2020-07-09 04:36:42
【问题描述】:

您好,我写了一个函数,将向量映射到区间 [0,1]:

fn vec2interval(v: &Vec<f32>) -> Vec<f32> {
    let total: f32 = v.iter().sum();
    let mut interval: Vec<f32> = vec![0f32; v.len()];
    interval[0] = v[0] / total;
    for i in 1..v.len() {
        interval[i] = interval[i-1] + v[i] / total;
    }
    return interval;
}

有没有办法用迭代器做同样的事情?我写了以下内容,但速度较慢,需要一个 for 循环:

fn vec2interval(v: &Vec<f32>) -> Vec<f32> {
    let total: f32 = v.iter().sum();
    let mut interval: Vec<f32> = v
        .iter()
        .map(|x| x / total)
        .collect::<Vec<f32>>();
    for i in 1..v.len() {
        interval[i] = interval[i-1] + interval[i];
    }
    return interval;
}

【问题讨论】:

标签: rust


【解决方案1】:

scan 可以完成所有工作:

fn vec2interval(v: &Vec<f32>) -> Vec<f32> {
    let total: f32 = v.iter().sum();

    v.iter()
        .scan(0.0, |acc, x| {
            *acc += x / total;
            Some(*acc)
        })
        .collect()
}

另外,最好使用切片 (&amp;[u8]) 代替 Vec&lt;_&gt; 作为参数。

【讨论】:

  • 删除map 并在scan 内进行除法可能更简单...
  • 谢谢!代码运行完美!它比简单的 for 循环慢一点,但很酷,希望更大的输入速度更快?
  • 迭代器在性能上有时可以是better,而其他时候可以是may suck。如果没有适当的基准测试,很难对其进行推理,如果您愿意,请查看quickcheck。还要考虑this解释。
猜你喜欢
  • 2015-04-11
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多