Bloom filterは指定されたものがリストに含まれるならばTrue、含まれないならばFalseを返すようなデータ構造である。もちろん、単純にリストを保持するだけでもリストに含まれるかどうかの判定は可能だが、Bloom filterのメリットはオリジナルのリストを保存しておく必要がないという点にある。そのためメモリの消費量を格段に節約することができる。しかし、そのメモリ効率の代償として多少正確性が失われる。Bloom filterは指定されたものがリストにない場合でもたまにTrueを返すのだ。しかし、間違ってTrueを返す確率はあらかじめ計算することができるので、誤差が許容できる範囲であれば問題なく使うことができる。
#!/usr/bin/perl use strict; use warnings; my $size = 1987; my $bitarray = ""; sub hashes { my ($str) = @_; my @xs = (0, 0, 0); for my $c (split(//, $str)) { my $o = ord($c); $xs[0] = ($xs[0] * 137 + $o) % $size; $xs[1] = ($xs[1] * 69 + $o) % $size; $xs[2] = ($xs[2] * 545 + $o) % $size; } return @xs; } sub add { my ($str) = @_; for my $x (hashes($str)) { vec($bitarray, $x, 1) = 1; } } sub query { my ($str) = @_; for my $x (hashes($str)) { return 0 unless vec($bitarray, $x, 1); } return 1; } while (<>) { chomp; my ($c, $k) = /^([aq]) (.+?)$/; if ($c eq "a") { add($k); } elsif ($c eq "q") { print query($k), "\n"; } }
% cat a.txt a hoge q hoge q hoga a foo a bar a baz q hoga q foo % ./bf.pl a.txt 1 0 0 1
2/17 | 24 | 3/3 | 10 | 17 | 24 | 31 | 4/7 | 14 | 21 | 28 | |
---|---|---|---|---|---|---|---|---|---|---|---|
ニンジン(加熱) | 5 | 7 | 5 | 6 | 6 | 7 | 7 | 6 | 6 | 4 | 7 |
小松菜(加熱) | 2 | 0 | 4 | 0 | 2 | 1 | 0 | 2 | 3 | 0 | 0 |
カブ(加熱) | 5 | 7 | 4 | 5 | 2 | 0 | 0 | 0 | 0 | 0 | 0 |
キャベツ(加熱) | 1 | 2 | 1 | 1 | 1 | 1 | 3 | 2 | 1 | 0 | 1 |
ダイコン(加熱) | 1 | 3 | 3 | 1 | 4 | 6 | 5 | 5 | 5 | 3 | 6 |
ジャガイモ(加熱) | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
サツマイモ(加熱) | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 3 | 1 |
ブロッコリー(加熱) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 1 | 3 | 6 |
ソーセージ(加熱) | 0 | 0 | 0 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
キュウリ | 6 | 6 | 7 | 7 | 7 | 7 | 7 | 6 | 6 | 4 | 7 |
サニーレタス | 2 | 0 | 0 | 0 | 6 | 3 | 0 | 0 | 0 | 0 | 0 |
グリーンカール | 3 | 1 | 0 | 0 | 0 | 5 | 1 | 0 | 0 | 0 | 0 |
レタス | 0 | 5 | 6 | 7 | 1 | 0 | 6 | 6 | 4 | 4 | 7 |
ベビーリーフ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 |
テンペ | 6 | 7 | 7 | 2 | 7 | 7 | 7 | 6 | 6 | 4 | 7 |
プチトマト | 6 | 7 | 7 | 7 | 4 | 7 | 5 | 4 | 6 | 4 | 7 |
トマト | 6 | 7 | 7 | 7 | 4 | 7 | 5 | 2 | 0 | 0 | 0 |
ゆでたまご | 0 | 1 | 1 | 1 | 0 | 1 | 2 | 4 | 5 | 4 | 6 |