【Ruby】木構造を定義してみる 2

2016年3月26日Ruby

こんにちは、しきゆらです

 

前回の記事で木構造を作るプログラムを書きましたが、子ノードの追加がわかりにくかったのですこし変更しました

なんで、前回の追加の仕方だったのかなどを合わせてメモしておきます

 


 

 

変更したコード

まずはコードを

Nodeクラス

class Node
  attr_accessor :value, :parent, :child
  def initialize(value, parent=nil)
    @value = value
    @child = []
    @parent = parent
  end
  
  def ==(node)
    @value == node.value
  end

  # 兄弟要素を返す
  def brothers
    unless @parent.nil? then
      @parent.child
    else
      nil
    end
  end

  # 子要素を追加
  def add_child!(value)
    @child.push(Node.new(value, self))
  end

  def to_s
    unless @parent.nil? then
      'value: ' + @value
    else
      'root'
    end
  end

  def search(value)
    # task_nameが一致するものを探す
    # この書き方だと、タテ型探索
    if @value == value then
      return self
    else
      @child.each do |n|
        node = n.search(value)
        if node then
          return node
        end
      end
      return nil
    end
  end

  def search_brothers(node)
    search(node.parent.task_name)
  end
end

 

変更した部分はadd_child!のところ

def add_child!(value)
    @child.push(Node.new(value, self))
  end

ちなみに、前回のadd_child!はこんな感じでした

def add_child!(node)
  if self == node.parent then
    @child.push(node)
  else
    @child.each do |n|
      n.add_child!(node)
    end
  end
end

とてもスッキリしました

 

ファイル読み込み関数

def make_tree(file_path)
  node = Node.new
  childs = []
  File.open(file_path).each_line do |lines|
    lines = lines.chomp.split(',')
    next if lines[0] == 'value'
    parent = lines.last
    value = lines.first
    p_node = node.search(parent)
    p_node.add_child!(value)
  end
  return node
end

 

ちなみに、前回のものは以下の通り

def make_tree(file_path)
  node = Node.new
  childs = []
  File.open(file_path).each_line do |lines|
    lines = lines.chomp.split(',')
    value = lines.first
    next if lines[0] == 'value'
    if lines.last == 'root' then
      t = Node.new(value, node)
      node.add_child!(t)
      childs.push(t)
    else
      childs.each do |n|
        if n.value == lines.last then
          tmp = Node.new(value, n)
          node.add_child!(tmp)
          childs.push(tmp)
          break
        end
      end
    end
  end
  return node
end

 

こちらも短くなりました

 

どうして前回の書き方だったのか

前回は、こう考えていました

最上位ノードが複数あるので、rootノードを最上位ノードの親ノードとしたいのでrootノードに子供を追加していかなければいけない

そして、作成するノードの親ノードもNodeクラスにしなければいけない

ということで、作成したノードを保持しておき一致したものを親ノードとしていけばいい、と

 

しかし、よくよく考えればmake_tree内でNode.newしないで

add_child!内でNode.newし、親要素としてselfを渡してやればいいということで

add_child!にはそのノードが持つ値valueを渡すように変更しました

 

この変更により、コードが短くなり流れがわかりやすくなったかと思います

 

今後もこれを使っていくので、どこかで変更したら追加で記事を書いていこうと思います

おわり

Posted by しきゆら