繁体   English   中英

如何将输入映射到具有相同输出和均匀分布保证的输出?

[英]How to map inputs to outputs with same output and uniform distribution guarantees?

我有一组可变大小N的输入(在我的情况下为String ),我需要映射到固定大小M一组输出(在我的情况下为数组的索引)。 因此,我基本上需要一个类似的功能:

fn map(input: String) -> usize;

我需要保证2件事情:

  1. 对于任何输入X我必须始终返回相同的输出Y 例如:每次我将字符串"hello"传递给函数时,返回的值必须始终相同,例如1
  2. 返回值的分布必须是均匀的,即对于无限数量的输入,相同返回值的平均值必须相同。 例如,如果我有M = 4不同的值要返回,而我有N = 100不同的输入,则映射到每个输出的输入数量必须理想地等于25

我想出了以下代码:

use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

fn main() {
    let bucket = Bucket::new(5);
    let inputs = ["hello", "world", "house", "hi"];

    for input in &inputs {
        let output = bucket.get(input);
        assert_eq!(output, bucket.get(input));
        println!("{} -> {}", input, output);
    }
}

pub struct Bucket {
    values: Vec<usize>,
}

impl Bucket {
    pub fn new(size: usize) -> Self {
        let values = (0..size).collect();
        Bucket { values }
    }

    pub fn get<T: Hash>(&self, id: &T) -> usize {
        let mut hasher = DefaultHasher::new();
        Hash::hash(id, &mut hasher);
        let index = (hasher.finish() % self.values.len() as u64) as usize;
        self.values[index]
    }
}

链接到游乐场

我认为上面的代码保证第一个点(对于相同的输入总是相同的输出),但不一定保证第二个点(分布的均匀性)。

是否有这种功能的快速实现,以确保两点都得到保证?

我认为您的实现的第一点是正确的。

关于第二点:这取决于DefaultHasher功能。 在实践中,这可能已经足够好了,但是还有另一种技术可以满足您的要求:

  • 有一个计数器m ,最初为0。
  • 有一个HashMap映射Stringusize
  • 每当您想要get结果时,请在HashMap查找给定的字符串:
    • 如果字符串已经存在,则返回关联的值。
    • 如果该字符串尚不存在:
    • HashMap中添加一个新条目,该条目将给定的字符串映射到m的当前值。
    • m递增1。
    • 如果m==M ,则将m==M重置为0。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM