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

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

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

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

Q&A

解決済

1回答

1827閲覧

クイックソート

GenkiNishiyama

総合スコア13

Ruby

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

0グッド

0クリップ

投稿2016/04/30 12:41

###前提・実現したいこと
ここに質問したいことを詳細に書いてください
『アルゴリズムを、はじめよう」という書籍を参考に、Rubyでクイックソートのプログラムを書いています。この書籍にはプログラミング言語による模範解答は載せられていないため、プログラムを自分で書く必要があります。
###発生している問題・エラーメッセージ
下記のコードを試した結果、おそらくですが、無限ループに陥ってしまいました。

エラーメッセージ

###該当のソースコード
Ruby
ここにご自身が実行したソースコードを書いてください
def quick_sort(array, left, right)
i = left + 1
k = right

while i < k
while array[i] < array[left] && i < right
i = i + 1
end

while array[i] >= array[left] && k > left k = k + 1 end if i < k w = array[left] array[left] = array[k] array[k] = w end

end

if left < k - 1
quick_sort(array, left, k - 1)
end

if k + 1 < right
quick_sort(array, k + 1, right)
end

end

array = [5, 4, 7, 6, 8, 3, 1, 2, 9]
quick_sort(array, 0, 8)

puts array

###試したこと
課題に対してアプローチしたことを記載してください
エラーメッセージが出ていた頃は、ひたすらそのエラーを潰していましたが、無限ループになってからは、エラーの原因がわかりません。webページも参考にしましたが、自分が書いたコードは動いてくれませんでした…。

###補足情報(言語/FW/ツール等のバージョンなど)
より詳細な情報
よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

... 無限ループになってからは、エラーの原因がわかりません。..

問題を解決するには、まずどこがループしているかを見つけることが必要です。
ソートする配列を単純なものから始めて、だんだんに複雑なものにしていって、動作を確認すると良いです。

質問文にあったコードは、配列のサイズが 1 のときは動作しました。
サイズが2になるとい無限ループしました。
どこでループしているかがわかるように puts を追加してみています。

ruby

1def quick_sort(array, left, right) 2 puts "quick_sort(left:#{left}, right:#{right})" 3 i = left + 1 4 k = right 5 6 puts 1 7 while i < k 8 puts 1.1 9 while array[i] < array[left] && i < right 10 i += 1 11 end 12 13 puts 1.2 14 while array[i] >= array[left] && k > left 15 k += 1 16 end 17 18 puts 1.3 19 if i < k 20 w = array[left] 21 array[left] = array[k] 22 array[k] = w 23 end 24 end 25 26 puts 2 27 if left < k - 1 28 quick_sort(array, left, k - 1) 29 end 30 31 if k + 1 < right 32 quick_sort(array, k + 1, right) 33 end 34end 35 36# array = [5, 4, 7, 6, 8, 3, 1, 2, 9] 37# array = [1] 38array = [1, 2] 39# array = [2, 1] 40quick_sort(array, 0, array.size) 41 42puts array

デバッガの使い方を覚えれば、puts 追加しなくても挙動を追うことができるようになります。
(ruby デバッグ などで google 検索してみてください)

プログラムが動作するように修正できたら、ぜひそれをここに投稿してください。
次は、プログラムの改善点などについてのコメントがもらえると思います。

投稿2016/04/30 13:47

katoy

総合スコア22324

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

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

GenkiNishiyama

2016/05/01 04:13

ありがとうございました! katoyさんのヒントをもとに動作するプログラムを書くことができました! 初めての質問でしたが、自分でウンウン悩んでいたら、もっと時間がかかっていたと思います。 ありがとうございました! 以下、コードです。 def quick_sort(array, left, right) i = left + 1 k = right while i < k puts "B" while array[i] < array[left] && i < right i = i + 1 end while array[k] >= array[left] && k > left k = k - 1 end if i < k w = array[i] array[i] = array[k] array[k] = w end end if array[left] > array[k] w = array[left] array[left] = array[k] array[k] = w end if left < k - 1 quick_sort(array, left, k - 1) end if k + 1 < right quick_sort(array, k + 1, right) end end array = [5, 4, 7, 6, 8, 3, 1, 2, 9] quick_sort(array, 0, array.size - 1) puts array
katoy

2016/05/01 05:59

ruby quicksort で検索すると、たくさんコード例を見つけることができます。 例えば Rubyでクイックソート [http://qiita.com/7kaji/items/5518479579bc36359bc8] などのコードとくらべてみると、よい勉強になるとおもいます。 参考として↓に ↑のコメントのコードを書き換えてものを記載します。 これは、 quick_sort() の中身を動作をかえずに短くし、 さらに配列の数が 7個, 8個 で値に重複がない場合にソートが正常動作していること の確認をするようにしています。 def quick_sort(array, left, right) i = left + 1 k = right while i < k i += 1 while array[i] < array[left] && i < right k -= 1 while array[k] >= array[left] && k > left array[i], array[k] = array[k], array[i] if i < k end array[left], array[k] = array[k], array[left] if array[left] > array[k] quick_sort(array, left, k - 1) if left < k - 1 quick_sort(array, k + 1, right) if k + 1 < right end array = [5, 4, 7, 6, 8, 3, 1, 2, 9] quick_sort(array, 0, array.size - 1) puts array.join(', ') [1, 2, 3, 4, 5, 6, 7].permutation(7) do |ar| quick_sort(ar, 0, ar.size - 1) fail "Can not sort #{ar.join}" if ar.join != '1234567' end [1, 2, 3, 4, 5, 6, 7, 8].permutation(8) do |ar| quick_sort(ar, 0, ar.size - 1) fail "Can not sort #{ar.join}" if ar.join != '12345678' end
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問