【发布时间】:2019-11-28 04:53:52
【问题描述】:
我有一组可变大小 N 的输入(在我的情况下为 Strings),我需要映射到一组固定大小的输出(在我的情况下为数组的索引)M .所以,我基本上需要这样的功能:
fn map(input: String) -> usize;
我需要保证两件事:
- 对于任何输入
X,我必须始终返回相同的输出Y。例如:每次我将字符串"hello"传递给我的函数时,返回的值必须始终相同,例如1。 - 返回值的分布必须是均匀的,也就是说,对于无数个输入,相同返回值的平均值必须相同。例如,如果我有
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]
}
}
我认为上面的代码保证了第一点(对于相同的输入总是相同的输出),但不一定是第二点(分布的均匀性)。
有没有快速实现这样的功能,从而保证两点?
【问题讨论】:
标签: hash rust mapping distribution uniform-distribution