2016-05-29 7 views
1

2次元ベクトルを初期化するコンストラクタを使ってRubyでクラスを作成する必要があります。 XとYはベクトルの長さです。このクラスでは、Vector2Dクラスのオブジェクトである2つのベクトルを追加するメソッドを作成する必要があります。オブジェクト指向Rubyでのベクトル追加

class Vector2D 
    def initialize(x, y) 
     @x = x 
     @y = y 
    end 
    def add 
     return "Vector addition" 
    end 
end 

vector1 = Vector2D.new(3,4) 
vector2 = Vector2D.new(1,2) 

puts vector1.add 

「追加」メソッドを実装する方法がわかりません。私はパラメータとしてこの2つのベクトルを送信する方法を知らないし、私はこのメソッドを呼び出す必要があるオブジェクトを知りません。

+0

を書くこと後ができますadd

alias_method :+, :add 

の定義を次の行を追加します

+0

あなたは '+'を使って 'vector1のようなコードを使って2つのベクトルを追加する方法を実装するには、この答えを見てみるといいかもしれません(http://stackoverflow.com/questions/5556124/ruby-defining-operator-procedure)。 + vector2' –

答えて

3

私はこれがあなたが望むかもしれないと信じています。彼らはもちろん、同じサイズでなければなりませんしなければならない別のものを追加するのに

コード

class Vector2D 
    attr_reader :x 

    def initialize(*x) 
    @x = x 
    end 

    def add(other) 
    x.zip(other.x).map { |x,y| x+y } 
    end 
end 

vector1 = Vector2D.new(3,4) 
vector2 = Vector2D.new(1,2) 

vector1.add(vector2) 
    #=> [4, 6] 

は方法は、任意のサイズのベクトルに対して動作します。

Vector2D.new(1,2,3,4).add Vector2D.new(5,6,7,8) 
    #=> [6, 8, 10, 12] 
Vector2D.new(1).add Vector2D.new(2) 
    #=> [3] 
Vector2D.new().add Vector2D.new() 
    #=> [] 

説明

initializeは引数*xと呼ばれています。 *は「スプラット」演算子と呼ばれます。 This linkは、どのように使用されているかをよく説明しています。 Class::newVector2D.new([3,4]))に配列を渡した場合、splat演算子は必要ありません。 (以下、その上より。)我々は

a = vector1.x.zip(vector2.x) 
    #=> [[3, 1], [4, 2]] 

を計算add

は次に

a.map { |x,y| x+y } 
    #=> [4, 6] 

x.zip(other.x).map { |x,y| x+y } 

self.x.zip(other.x).map { |x,y| x+y } 
と同じです

これは、メソッド(ここではgetter x)に明示的なレシーバがない場合(受信者がself.xselfと書いた場合のように)、受信者はselfとみなされます。 my_methodが安全になった場合は、多くの場合、self.my_methodが表示されます。 Rubiestsの中には、たとえそれが不必要であることが分かっていても、もっと明確に思えるので、Rubiestsの前者を選ぶ人もいます。私はそのキャンプにいることはありません。

我々は代わりに直接ではなく、そのゲッターを通じて@x変数のインスタンスを参照する

@x.zip(other.x).map { |x,y| x+y } 

を書くことができます。どちらの方法も問題ありません。

def initialize(x) 
    @x = x 
    end 

vector1 = Vector2D.new([3,4]) 

をあなたは、配列を渡している強調すること:書くことが好ましいかもしれない

観察

。二つの配列が同じ長さである場合には

あなたは、交換可能にEnumerable#zipArray#transposeを使用することができます。

def add(other) 
    [x, other.x].transpose.map { |y,z| y+z } 
end 

だこと、あなたが渡すあなたがオブジェクト指向の方法で、二つのベクトルを追加したい場合は

[3,4].zip([1,2]) 
    #=> [[3, 1], [4, 2]] 
[[3,4], [1,2]].transpose 
    #=> [[3, 1], [4, 2]] 
+0

私は、varargsのコンストラクタだけでなく、map/zip/transposeもovであると思いますエルキル、そしておそらくOPのために進歩する方法。 また、私は操作の結果としてVector2Dを返すだろう。 –

1

、なぜならaddメッセージを送信したときに結果を返すと、1つのベクトルを他のベクトルに引数として渡します(ゼロにすることもできます)。一般的に

これは次のようになります。だからあなたのベクトルはのparamとして他のベクターをとるadd方法を持っている必要があり

result = receiver.message(argument) 

。私は新しいベクトルを結果として返します(しかし、x/yの配列も返すことができます)。計算を続行できます。あなたは、ベクトル計算に有用な他の操作を追加することができます。同様に

class Vector2D 
    attr_reader :x, :y 

    def initialize(x, y) 
    @x = x 
    @y = y 
    end 

    def add(other) 
    Vector2D.new(x + other.x, y + other.y) 
    end 

    def inspect 
    "(#{x},#{y})" 
    end 
end 


vector1 = Vector2D.new(3,4) 
vector2 = Vector2D.new(1,2) 

vector3 = vector1.add(vector2) 

p vector1 # => (3,4) 
p vector2 # => (1,2) 
p vector3 # => (4,6) 
p vector3.add(vector3) #)> (8,12) 

。おそらくlengthまたはsubtractなどです。

そして、あなたはあなたが+にメソッドaddを別名設定できるいくつか糖衣構文を追加したい場合。おそらく、このリンクがhttps://en.wikibooks.org/wiki/Ruby_Programming/Writing_methodsを助ける

vector3 = vector1 + vector2 
+0

OPはメソッドが2つの要素を持つ配列でしか動作しないようにしたいと思っています。 –

+0

これはVector2Dです。 –

+0

私はいつもベクトルが "1D"であると考えました。 –

関連する問題