4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ruby でハッシュテーブルを実装する

Last updated at Posted at 2012-12-26

ハッシュテーブルというデータ構造について理解するために書いた.

ここを参考に.
http://www.geocities.jp/ky_webid/algorithm/014.html

hash_table.rb
# coding: utf-8
class HashTable
  class Bucket
    attr_reader :key, :value, :next_cell

    def initialize(key, value, next_cell = nil)
      @key, @value, @next_cell = key, value, next_cell
    end
  end

  TABLE_SIZE = 10

  def initialize
    @table = Array.new(TABLE_SIZE)
  end

  def []=(key, value)
    raise '既に存在するキーです' unless self[key].nil?

    hash_key = hash(key)
    cell = Bucket.new(key, value, @table[hash_key])
    @table[hash_key] = cell
  end

  def [](key)
    hash_key = hash(key)
    cell = @table[hash_key]
    while cell do
      return cell.value if cell.key == key
      cell = cell.next_cell
    end
  end

  private
  def hash(key)
    key % TABLE_SIZE
  end
end
hash_table_spec.rb
# coding: utf-8
require './hash_table'

describe HashTable do
  let(:table) { HashTable.new }

  context 'キーに値が存在しないとき' do
    subject { table[0] }
    it { should be_nil }
  end

  context 'キーに値が存在するとき' do
    before { table[0] = :foo }
    subject { table[0] }
    it { should == :foo }
  end

  context '既に値が存在するキーにもう一度値をセットしたとき' do
    before { table[0] = :foo }
    it 'エラーを投げる' do
      proc { table[0] = :bar }.should raise_error
    end
  end

  context 'ハッシュが競合するキーに値をセットしたとき' do
    before do
      table[0] = :foo
      table[10] = :bar
    end

    it { table[0].should == :foo }
    it { table[10].should == :bar }
  end
end

データ構造がどういう風になっているか, pp で示してみる.

test.rb
require './hash_table'
require 'pp'

ht = HashTable.new
ht[0] = :foo
ht[1] = :bar
ht[10] = :baz # 0 とハッシュが競合

pp ht
#<HashTable:0x007fa0c282cbd8
 @table=
  [#<HashTable::Bucket:0x007fa0c282ca98
    @key=10,
    @next_cell=
     #<HashTable::Bucket:0x007fa0c282cb38 @key=0, @next_cell=nil, @value=:foo>,
    @value=:baz>,
   #<HashTable::Bucket:0x007fa0c282cae8 @key=1, @next_cell=nil, @value=:bar>,
   nil,
   nil,
   nil,
   nil,
   nil,
   nil,
   nil,
   nil]>
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?