[English]
Version: 0.56.27 (2002.03.11) Author: 原信一郎 (sinara@blade.nagaokaut.ac.jp)
これは集合と写像を表現する Ruby のライブラリです。
これは "Algebra" ライブラリの一部分として作成されました。
lib/*.rb を Ruby がロード可能なディレクトリにコピーしてください。
集合を作るには Set[] を使います。返り値は Set オブジェクトであり、
集合の結び、交わり等基本的な演算が使えるようになります。eql? で等しい
要素は 1 つに数えられます。要素を表示させたときの要素の順番は不定です。
また、写像を作るには Map[] を使います。
例:
require "finite-set"
include Algebra
s = Set[3, 0, 1, 2, 3]
p s #=> {0, 1, 2, 3}
t = Set[2, 3, 4, 5]
p s & t #=> {2, 3}
p s | t #=> {5, 0, 1, 2, 3, 4}
require "finite-map"
m = Map[0 => 10, 1 => 11, 2 => 21, 3 => 31]
p m.image(s) #=> {10, 31, 21, 11}
Set, Map 共に処理の高速化のためにデータを Hash オブジェクトとして 保持しています。したがって、要素の同一性は(== でなく)eql? で行わ れます。そして、ユーザーが定義したクラスのインスタンスを要素に するには、eql? と hash メソッドを、目的に合うように 定義しなおさなければなりません。特に
a.eql?(b) が真の時、必ず a.hash == b.hash が成り立つ
ように、eql? と hash を定義しておく必要があります。 次は2次元ベクトルのクラスの例です。
例:
class Vector
attr_accessor :x, :y
def initialize(x, y)
@x, @y = x, y
end
def eql?(other)
@x == other.x and @y == other.y
end
alias == eql?
def hash
@x.hash ^ @y.hash
end
def inspect
"[#{@x.inspect}, #{@y.inspect}]"
end
end
v0, v1 = Vector.new(0, 1), Vector.new(1, 2)
s = Set[v0, v1]
p s.has? Vector.new(0, 1) #=> true
ただし、組み込みのクラスに対してはすでに eql? と hash は適切に定義済みです。
たとえ組み込みクラスのインスタンスが要素であっても、インスタンスの 状態が変化すると、集合から取り出すことができなくなります。 この障害は Set#rehash により回復できます。
例
a = [0, 1]
b = [1, 2]
s = Set[a, b]
a[0] = 10
p s #=> {[1, 2], [10, 1]}
p s.has? [10, 1] #=> false
s.rehash
p s.has? [10, 1] #=> true