8
class CartesianProduct
include Enumerable
# your code here
end
#Examples of use
c = CartesianProduct.new([:a,:b], [4,5])
c.each { |elt| puts elt.inspect }
# [:a, 4]
# [:a, 5]
# [:b, 4]
# [:b, 5]
c = CartesianProduct.new([:a,:b], [])
c.each { |elt| puts elt.inspect }
# (nothing printed since Cartesian product
# of anything with an empty collection is empty)

私はルビーに不慣れです。デカルト積のインスタンスメソッドを定義する方法は理解していますが、これについての手がかりはありません。要件を満たすためにクラスオブジェクトをどのように構築する必要がありますか。

4

3 に答える 3

29

を使用することをお勧めしArray#productます。

[:a, :b].product [4,5]

これにより、必要な出力が得られます。

irb(main):001:0> [:a, :b].product [4,5]
=> [[:a, 4], [:a, 5], [:b, 4], [:b, 5]]
irb(main):002:0> 

順列の怠惰なジェネレーターが必要な場合は、以前にこのようなものを作成しました。ただし、計算する順列が多数ある場合は、時間がかかる可能性があることを警告します。このファイルの最初の40〜45行から必要なものを取得できるはずです(このファイルはとにかく実験でした)。

秘訣は、Ruby 1.9.2を使用して列挙子を作成し、配列の配列を処理することです。したがって、最初に配列を無限に循環する列挙子を作成し、配列の配列列挙子で最初の出力セットを追跡し、それが2回目にヒットしたときにループを終了します。これが、そのようなループを終了する方法を理解する唯一の方法でした。

def infinite_iterator(array)
  Enumerator.new do |result|
    loop do
      array.cycle { |item| result << item }
    end
  end
end

def cartesian_iterator(data)
  Enumerator.new do |result|
    first = data.map { |p| p.next }
    result << first

    i = 1
    parts = first.dup
    loop do
      parts[2-i] = data[2-i].next
      break if parts == first

      result << parts.join
      i = ((i + 1) % parts.size)
    end
  end
end

array = [ infinite_iterator([:a,:b]), infinite_iterator([4,5]) ]
generator = cartesian_iterator(array)

generator.each { |a| p a }
于 2012-07-05T20:36:47.820 に答える
8

そのためのクラスは使用しませんが、質問の構造を維持しながら、次のように記述します。

class CartesianProduct
  include Enumerable

  def initialize(xs, ys)
    @xs = xs
    @ys = ys
  end

  def each
    return to_enum unless block_given?
    @xs.each do |x| 
      @ys.each { |y| yield [x, y] }
    end
  end
end

代わりに、怠惰が重要な場合はxs.product(ys)、自分で作成または作成するだけです(このチケットを参照)。Array#lazy_product

于 2012-07-05T21:22:36.233 に答える
7

製品のすべての組み合わせをeach呼び出すメソッドをクラスで定義する必要があります。yield

を使用することもできますArray#productが、配列を返すため、遅延はありません。

それを行うRuby2.0の提案Array.productがあります。

于 2012-07-05T20:36:57.440 に答える