String
可変サイズの一連の入力 (私の場合はs) がN
あり、固定サイズの一連の出力 (私の場合は配列のインデックス) にマップする必要があります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]
}
}
上記のコードは、1 番目のポイント (同じ入力に対して常に同じ出力) を保証しますが、2 番目のポイント (分布の均一性) を保証するとは限りません。
両方のポイントが保証されるように、そのような関数の高速な実装はありますか?