[英]How to map inputs to outputs with same output and uniform distribution guarantees?
我有一组可变大小N
的输入(在我的情况下为String
),我需要映射到固定大小M
一组输出(在我的情况下为数组的索引)。 因此,我基本上需要一个类似的功能:
fn map(input: String) -> usize;
我需要保证2件事情:
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]
}
}
我认为上面的代码保证第一个点(对于相同的输入总是相同的输出),但不一定保证第二个点(分布的均匀性)。
是否有这种功能的快速实现,以确保两点都得到保证?
我认为您的实现的第一点是正确的。
关于第二点:这取决于DefaultHasher
功能。 在实践中,这可能已经足够好了,但是还有另一种技术可以满足您的要求:
m
,最初为0。 HashMap
映射String
要usize
。 get
结果时,请在HashMap
查找给定的字符串:
HashMap
中添加一个新条目,该条目将给定的字符串映射到m
的当前值。 m
递增1。 m==M
,则将m==M
重置为0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.