1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rubyで二分探索法を書いてMinitestでテストしてみた

Posted at

#はじめに
今回はこちらの本でアルゴリズムの勉強をしているので学んだことをRubyで書いて見ました。
アルゴリズムをはじめよう
こちらの記事を参考にさせていただいてます。
Rubyで二分探索法(バイナリサーチ)を書いてみた

#二分探索法
二分探索法は予め、昇順か降順に整列されているデータが対象で、探索する範囲を半分に絞りながら探索を進めます。
手順は
①配列の真ん中の要素を求める
②真ん中のデータと目的のデータを比較する(一致したら探索終了。一致しない場合③へ)
③比較したデータが目的のデータより大きいか小さいか確認して探索の範囲を半分に狭める。
以降①→③を繰り返す。

配列の真ん中の要素を求める為に「head」と「tail」という二つの変数を用意。
真ん中を求めるには配列の先頭と末尾を足して2でわる。割り切れない場合は小数点を切り捨てます。(整数型の場合自動的に切り捨てになります。)

はじめに書いたコードはこんな感じでした。

def binary_search(array,target)
    #配列の真ん中を求める為下準備
    head =0
    tail =(array.count)-1

    loop do
        if head <= tail
          #①配列の真ん中の要素を求める
          center = (head+tail)/2
          #②真ん中のデータと目的のデータを比較する(一致したら探索終了。一致しない場合③へ)
          if array[center] == target
            return center
          #③比較したデータが目的のデータより大きいか小さいか確認する。
          else
            if array[center] < target
                head =center+1
            else
                tail =center-1
            end
          end
        else 
            #目的の値が見つからない場合−1を返す。
            return -1
        end
    end
end

テスト

require 'minitest/autorun'
require './irb/binary.rb'

class BinaryTest < Minitest::Test
  def test_binary
    assert_equal  6,binary_search([11,13,17,19,23,29,31],31)
    assert_equal  -1,binary_search([11,13,17,19,23,29,31],35)
    assert_equal  0,binary_search([11,13,17,19,23,29,31],11)
    assert_equal  0,binary_search([11,13,17],11)
    assert_equal  -1,binary_search([11,13,17],15)
    assert_equal  3,binary_search([11,13,17,67],67)
  end  
end

テスト実行。

ruby test/binary_test.rb
Finished in 0.000620s, 1612.9031 runs/s, 9677.4184 assertions/s.

1 runs, 6 assertions, 0 failures, 0 errors, 0 skips

###リファクタリング
途中でloopメゾットを使っていますが、条件が真である間処理を繰り返すwhile文を使う等して見やすいコードにしました。

def binary_search(array,target)
  head =0
  tail =(array.count)-1

    while head <= tail
      center = (head+tail)/2

      if array[center] == target
        return center

      elsif array[center] < target
        head =center+1
          
      else
        tail =center-1
      end   
    end
    return -1
end

※フォルダ構成はこのようにしてあります。

ruby
├── irb  
│   └── binary.rb
└── test
    └── binary_test.rb

最後までお読みいただきありがとうございました。アドバイス等あればコメントいただけると幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?