質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Q&A

解決済

1回答

1676閲覧

ruby にて "no method error"が出ます

shocyu

総合スコア17

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

0グッド

0クリップ

投稿2015/10/12 07:16

ruby にて2分木を作るアルゴリズムを書いています(参考:紀平拓男、春日伸弥「アルゴリズムとデータ構造」SoftbankCreative)まず Binary_Tree_Node クラスを作成し、その中に insert_node, find_value, delete_tree, print_treeメソッドを作成しました。

後半のメイン処理の部分で、まず insert_node メソッドを呼び出す際に、”undefined method for Binary_Tree_Node class(no method error) のような形でエラーが出ます。以下のソースではクラスの中にクラスメソッドとして作成しているのですが、なぜエラーが出るのでしょうか?

教えていただけますと嬉しくぞんじます。よろしくお願いします。

(以下ソース)

ruby

1#---------------------------------------------------------------------------------# 2# Binary_Tree_Node クラス(2分木の1つのノード) 3class Binary_Tree_Node 4 5 #インスタンス変数は参照と更新可能 6 attr_accessor :value 7 attr_accessor :left 8 attr_accessor :right 9 10 #コンストラクタ 11 def initialize(num = 0) 12 @value = num 13 @left = nil 14 @right = nil 15 end 16 17 # insert_nodeメソッド=枝の挿入(num が親ノードより小さければ左、大きければ右) 18 def insert_node(num, node) 19 if (node.left == nil) && (node.right == nil) 20 tree_root = Binary_Tree_Node.new 21 return 22 end 23 24 if node.value > num 25 if node.left != nil 26 insert_node(num, node.left) 27 else 28 node.left = Binary_Tree_Node.new(num) 29 end 30 else 31 if node.right != nil 32 insert_node(num, node.right) 33 else 34 node.right = Binary_Tree_Node.new(num) 35 end 36 end 37 38 return 39 end 40 # insert_nodeメソッド終わり 41 42 # find_valueメソッド=探している値を持つ node を見つける 43 def find_value(node, val) 44 if node.value > val 45 if node.left == nil 46 return nil 47 end 48 49 return find_value(node.left, val) 50 end 51 52 if node.value < val 53 if node.right == nil 54 return nil 55 end 56 57 return find_value(node.right, val) 58 end 59 60 return node 61 end 62 # find_value メソッド終わり 63 64 # delete_tree メソッド(ノードの削除) 65 def delete_tree(val) 66 node = Binary_Tree_Node.new 67 parent_node = Binary_Tree_Node.new 68 69 direction = 0 70 71 # while 文で削除すべき対象を見つける 72 while node != nil && node.value != val do 73 if node.value > val 74 parent_node = node 75 node = node.left 76 diretion = -1 77 else 78 parent_node = node 79 node = node.right 80 diretion = 1 81 end 82 end 83 84 if node == nil 85 #見つからなかった 86 return false 87 end 88 89 # 左か右、どちらかが nil であった場合(両方 nil の場合も含む) 90 if node.left == nil || node.right == nil 91 if node.left == nil 92 # 親のポインタを変更する 93 if diretion == -1 94 paretnt_node.left = node.right 95 elsif diretion == 1 96 parent_node.right = node.right 97 elsif direction == 0 98 tree_root = node.right 99 end 100 else 101 # 親のポインタを変更する 102 if direction == -1 103 parent_node.left = node.left 104 elsif direction == 1 105 parent_node.right = node.left 106 elsif direction == 0 107 tree_root = node.left 108 end 109 end 110 # 両者とも nil でなかった場合 111 # node の左側の、最も大きな値(最も右側の値)を取得する 112 else 113 left_biggest = Binary_Tree_Node.new 114 left_biggest = node.left 115 parent_node = node 116 direction = -1 117 118 while left_biggest.right != nil 119 parent_node = left_biggest 120 left_biggest = left_biggest.right 121 direction = 1 122 end 123 124 # left_biggest の値を node に代入し 125 # left_biggest は左側の枝を入れる 126 node.value = left_biggest.value 127 128 if direction == -1 129 parent_node.left = left_biggest.left 130 else 131 parent_node.right = left_biggest.left 132 end 133 end 134 135 return true 136 end 137 # delete_tree メソッド終わり 138 139 # print_tree メソッド(木の状態を出力する) 140 def print_tree(depth, node) 141 if node == nil 142 return 143 end 144 145 print_tree(depth + 1, node.left) 146 147 for i in 0..depth do 148 print " " 149 end 150 151 print node.value.to_s 152 print "\n" 153 print_tree(depth + 1, node.right) 154 end 155 # print_tree メソッド終わり 156 157end 158# Binary_Tree_Node クラス終わり 159#---------------------------------------------------------------------------------# 160 161#メイン処理(情報を入力し、木を作成(Binary_Tree_Node クラスメソッドを用いて)) 162i, action, N = 0, 0, 0 163random_value = 0 164tree_root = Binary_Tree_Node.new 165 166puts "Start making tree" 167 168for i in 0..10 do 169 random_value = Random.rand(100) 170 171 Binary_Tree_Node.insert_node(random_value, tree_root) 172end 173 174puts "Number of Trial" 175N = gets.to_i 176 177# N 回以下の処理を繰り返し(1:追加、2:検索、3:削除、4:終わり) 178for i in 0..(N - 1) do 179 Binary_Tree_Node.print_tree(0, tree_root) 180 181 puts "Select Control" 182 puts "1:add, 2:search, 3:delete, 4:end" 183 action = gets.to_i 184 185 case action 186 when 1 187 puts "Put number from 0 to 100" 188 i = gets.to_i 189 190 if i < 1 || i > 100 191 redo 192 end 193 194 Binary_Tree_Node.insert_node(i, tree_root) 195 when 2 196 puts "Put the number to find" 197 i = gets.to_i 198 199 if Binary_Tree_Node.find_value(tree_root, i) != nil 200 puts "The number" + i.to_s + "is found" 201 else 202 puts "The number" + i.to_s + "couldn't be found" 203 end 204 when 3 205 puts "Put the number to delete" 206 i = gets.to_i 207 208 if Binary_Tree_Node.delete_tree(i) 209 puts "The number" + i.to_s + "is deleted" 210 else 211 puts "The number" + i.to_s + "couldn't be found" 212 end 213 when 4 214 return 215 end 216end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Binary_Tree_Node.insert_node(i, tree_root)
でエラーにならないようにしたいなら、
def self.insert_node(num, node )
のように insert_node は定義する必要があります。

このエラーを解消させただけではプログラムが動作しなかったので、それなりに動作するように変更をしてみました。

ruby

1# coding: utf-8 2#-----------------------------------------------# 3# Binary_Tree_Node クラス(2分木の1つのノード) 4class BinaryTreeNode 5 # インスタンス変数は参照と更新可能 6 attr_accessor :value, :left, :right 7 8 # コンストラクタ 9 def initialize(num = 0) 10 @value = num 11 @left = nil 12 @right = nil 13 end 14 15 # 節の挿入(num が親ノードより小さければ左、大きければ右, 同じなら何もしない) 16 def insert_node!(num = 0) 17 if @value == num 18 # 何もしない 19 else 20 if num < @value 21 if @left.nil? 22 @left = BinaryTreeNode.new(num) 23 else 24 @left.insert_node!(num) 25 end 26 else 27 if @right.nil? 28 @right = BinaryTreeNode.new(num) 29 else 30 @right.insert_node!(num) 31 end 32 end 33 end 34 end 35 36 # 探している値を持つ節を見つける 37 def find_value(num) 38 ans = nil 39 if @value == num 40 ans = self 41 elsif num < @value 42 ans = @left.find_value(num) if @left 43 elsif @value < num 44 ans = @right.find_value(num) if @right 45 end 46 ans 47 end 48 49 # node 以下の最小値の節を探す 50 def serach_min(node) 51 node = node.left while node.left 52 node 53 end 54 55 # node 以下の最小値の節を削除する 56 def delete_min!(node) 57 return node.right unless node.left 58 node.left = delete_min!(node.left) 59 node 60 end 61 62 # node 以下の 値が num の節を削除 63 def delete_tree!(node, num) 64 if node 65 if num == node.value 66 if node.left.nil? 67 return node.right 68 elsif node.right.nil? 69 return node.left 70 else 71 min_node = serach_min(node.right) 72 node.value = min_node.value 73 node.right = delete_min!(node.right) 74 end 75 elsif num < node.value 76 node.left = delete_tree!(node.left, num) 77 else 78 node.right = delete_tree!(node.right, num) 79 end 80 end 81 node 82 end 83 84 # 木の状態を出力する 85 def print_tree(depth = 0) 86 @left.print_tree(depth + 1) if @left 87 puts "#{' ' * depth}#{@value}" 88 @right.print_tree(depth + 1) if @right 89 end 90end 91 92#-----------------------------------------------# 93# メイン処理(情報を入力し、木を操作する) 94tree_root = BinaryTreeNode.new 95 96puts 'Start making tree.' 9710.times do 98 random_value = Random.rand(100) 99 tree_root.insert_node!(random_value) 100end 101 102puts 'Number of Trial.' 103action_count = gets.to_i 104# 以下の処理を最大でn回だけ繰り返す。 105action_count.times do 106 puts 'Select Control. (a:add, s:search, d:delete, p:print, q:end)' 107 case gets.strip.downcase 108 when 'a' 109 puts 'Put number.' 110 num = gets.to_i 111 tree_root.insert_node!(num) 112 when 's' 113 puts 'Put the number to find.' 114 num = gets.to_i 115 if tree_root.find_value(num) 116 puts "The number #{num} is found." 117 else 118 puts "The number #{num} is not found." 119 end 120 when 'd' 121 puts 'Put the number to delete.' 122 num = gets.to_i 123 if num == 0 124 puts 'The tree_root can not delete.' 125 elsif tree_root.find_value(num).nil? 126 puts "The number #{num} couldn't be found." 127 else 128 tree_root.delete_tree!(tree_root, num) 129 puts "The number #{num} is deleted." 130 end 131 when 'p' 132 tree_root.print_tree 133 when 'q' 134 break # 終了 135 end 136end

2分木の操作例としては以下が参考になるかもしれません。
参考

投稿2015/10/12 15:33

katoy

総合スコア22322

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shocyu

2015/10/13 06:24

katoyさん、本当にありがとうございます!修正いただいたコードを一通り理解してからお返事を差し上げようと思い、返信が遅くなりました。 木構造がアルゴリズムの基本だということが深く理解できました。あとオブジェクト指向を用いる利点をさらに理解できました。 ruby のコードはここまで美しく書けるんですね。また精進したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問