###前提・実現したいこと
rubyを用いて、bloomfilterの機能が搭載されている検索システムを作っています。
bloomfilterには適当な英単語を十数個登録してビット値として配列に格納します。そして検索機能を設置し、入力された英単語が登録された英単語にあるならpositiveを、ないならnegativeを返すように作ります。
###発生している問題・エラーメッセージ
bloomfilterの配列に格納されている値と、検索した文字列の値が食い違い、Negativeになってしまいます。(False negativeが発生する) 例(実際にコードを走らせて見た場合)) Snowstorm, Downpour, Rainstorm, Blusterous, Lightning, Sleety, Hail, Sunny, Cloudy, //bloomfilterに登録されている英単語 11011010100010101111001000101101 //bloomfilterの配列 Weather Search search: s hoge|終了(exit): e コマンドs Snowstorm search s Snowstorm 25 5 16 index: 11011010100010101111001000101101 KEYS: 00000100000000001000000001000000 //登録してある単語で検索すると、何故か入ってない場所にビットが立つ i: 25 -> 0|1i: 5 -> 0|1i: 16 -> 1|1
###該当のソースコード
ruby
1# coding: utf-8 2require 'digest' 3#Digest::MD5.haexdigest('hoge').to_s 4 5SIZE = 32 6BFINDEX = Array.new(SIZE){0} 7S = [13, 211, 928] 8 9 10def hash(obj) 11 h = Array.new(3){0}; 12 13 S.length.times do |i| 14 tmp = 0 15 md5 = Digest::MD5.hexdigest(obj.to_s + S[i].to_s).unpack("B*") 16 17 md5.to_s.each_char.with_index { |c, i| 18 if c.to_i == 1 then 19 tmp+=1 20 end 21 } 22 h[i] = (tmp + S[i]) % SIZE 23 end 24 25 return h 26end 27 28# Bloom Filter 29def reg(obj) 30 keys = hash(obj).flatten 31 32 keys.each do |key| 33 BFINDEX[key] = 1 34 end 35end 36 37 38 39 40def search(obj) 41 puts obj 42 key = hash(obj) #.flatten 43 filter = 0 44 45 tmp = Array.new(SIZE){0} 46 47 puts key 48 49 key.each do |k| 50 tmp[k] = 1 51 end 52 53 print("index: ", BFINDEX.join(""), "\nKEYS: ", tmp.join(""), "\n") 54 55 key.each do |i| 56 print("i: ", i, " -> ",BFINDEX[i] , "|",tmp[i]) 57 if BFINDEX[i] != 0 then 58 filter = filter + 1 59 end 60 end 61 62 if filter == 3 63 print("\npositive\n\n") 64 else 65 print("\nnegative\n\n") 66 end 67end 68 69 70 71 72# Main 73 74words = ["Snowstorm","Downpour","Rainstorm","Blusterous","Lightning","Sleety","Hail","Sunny","Cloudy"] 75 76 77words.each do |cats| 78 print(cats, ", ") 79 reg(cats) 80 81end 82 83puts 84 85print(BFINDEX.join(""), "\n") 86 87begin 88 89while true 90 puts "Weather Search" 91 puts "search: s hoge|終了(exit): e" 92 print("コマンド") 93 num = gets.chomp 94 95 case num 96 97 when /s / 98 puts "search" 99 x = num.split('search ') 100 search(x) 101 when 'e' 102 break 103 end 104end 105 106rescue Interrupt 107 exit() 108end 109 110
###試したこと
ハッシュ値を変えたり、ハッシュ関数そのものを変える、rubyのバージョンを変えるなど試みてみましたが同様の問題が発生します。
ハッシュ値は3つのつもりで作ってましたが、4つでも5つでも同様のエラーが起こるので取り敢えず原因を知りたく思い、皆様の知恵をお借りしたく思います。
###補足情報(言語/FW/ツール等のバージョンなど)
VMware Workstation 12 playerを使用し、ubuntu 64bitの仮想環境でターミナルを用いて実行・制作しています
ruby2.2.2です。
あなたの回答
tips
プレビュー