マップとハッシュ(ハッシュマップ)
7月 13th, 2008 admin Posted in Ruby, アルゴリズムとデータ構造 |
今回は「アルゴリズムとデータ構造シリーズ」です。前回に続いて第7章「マップとハッシュ」のハッシュマップの実装について。
ハッシュ値が重複した場合の対策
ハッシュ値が重複した場合には「k^2番目に再ハッシュする」という方法で対応した。
たとえばハッシュ値が2だった場合には
・3(2+1*1)
・6(2+2*2)
・11(2+3*3)
と試していく方法だ。
コード
検索と削除の部分は少しずるをしました。
RUBY:
-
#Hash Map
-
$KCODE = "SJIS"
-
-
class WordSet
-
attr_accessor :english, :japanese
-
def initialize(english = nil, japanese = nil)
-
@english = english
-
@japanese = japanese
-
end
-
end
-
-
class HashMap
-
def initialize(size)
-
@hash_table_size = size
-
@hash_table = Array.new
-
end
-
-
def make_hash(str)
-
weight = 0
-
hash = 0
-
str.each_byte{|s|
-
weight = 0 if weight> 7
-
hash += s * (256 ** weight)
-
weight+=1
-
}
-
hash % @hash_table_size
-
end
-
-
def add_data(ws)
-
hash_val = self.make_hash(ws.english)
-
-
unless @hash_table[hash_val].nil?
-
hash_val = self.rehash(hash_val)
-
if(hash_val == -1)
-
printf("%sをマップに挿入しようとしましたが、空き位置がありませんでした",ws.english)
-
return
-
end
-
end
-
-
@hash_table[hash_val] = ws
-
end
-
-
def rehash(first_hash_val)
-
#k^2に再ハッシュする
-
(1...(@hash_table_size/2)).each do |k|
-
hash_val = (first_hash_val+k*k) % @hash_table_size
-
return hash_val if @hash_table[hash_val].nil?
-
end
-
return -1
-
end
-
-
def find(str)
-
hash_val = self.make_hash(str)
-
return @hash_table[hash_val]
-
end
-
-
def delete(str)
-
hash_val = self.make_hash(str)
-
@hash_table[hash_val] = nil
-
return true
-
end
-
-
def print_all_data
-
@hash_table.each do |val|
-
printf("%s\t\t%s\n",val.english,val.japanese) unless val.nil?
-
end
-
end
-
end
-
-
init_data = [
-
WordSet.new("lisp","リスプ"),
-
WordSet.new("C","シー"),
-
WordSet.new("ruby","ルビー"),
-
WordSet.new("perl","パール"),
-
WordSet.new("python","パイソン"),
-
WordSet.new("PHP","ピーエイチピー"),
-
WordSet.new("JavaScript","ジャバスクリプト")
-
]
-
-
hash_map = HashMap.new(503)
-
-
init_data.each do |ws|
-
hash_map.add_data(ws)
-
end
-
-
i = nil
-
loop do
-
print "コマンドを入力して下さい\n1:表\ 2:検索 3:削除\n"
-
i = gets.chomp.to_i
-
-
case i
-
when 1
-
hash_map.print_all_data
-
when 2
-
print "検索する文字列を入力してください:"
-
j = gets.chomp
-
if ws = hash_map.find(j)
-
printf("%sは日本語で「%s」です。 \n\n",ws.english,ws.japanese)
-
else
-
print("見つかりませんでした。\n\n")
-
end
-
when 3
-
print "削除する文字列を入力してください:"
-
j = gets.chomp
-
if hash_map.delete(j)
-
printf("削除しました。 \n\n")
-
else
-
print("見つかりませんでした。\n\n")
-
end
-
end
-
end
まとめ
ハッシュというものがどういうものか(そもそもなんでハッシュと呼ばれているのか)わかって非常にすっきりできた。
※このシリーズは私がRubyでアルゴリズムとデータ構造を基礎から学ぶ記録です。全体の目次はこちらへ。
Leave a Reply