1

String可変サイズの一連の入力 (私の場合はs) がNあり、固定サイズの一連の出力 (私の場合は配列のインデックス) にマップする必要があります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]
    }
}

遊び場へのリンク

上記のコードは、1 番目のポイント (同じ入力に対して常に同じ出力) を保証しますが、2 番目のポイント (分布の均一性) を保証するとは限りません。

両方のポイントが保証されるように、そのような関数の高速な実装はありますか?

4

1 に答える 1