[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