社会不適合破壊的お味噌マン

くまのプーさんのような大人になりたいです!

探索アルゴリズムについて

  1. 線形探索(リニアサーチとは)と二分探索(バイナリーサーチ)の違い

1.線形探索(リニアサーチとは)と二分探索(バイナリーサーチ)の違い

線形探索とは先頭から順に配列を検索する方法。データーに規則性がない場合有効だけれど、計算時間がかかる。 二分探索とはデータが昇順で並んでいた場合、最初に真ん中に位置するデータと比較する。そうすることでどちらか一方のデータは計算しなくてよくなる。

例えば以下のような配列があって3を探したいとする。

[1, 3, 5, 7, 9, 11]

真ん中の数字は6なので、左側にあることがわかる。

2.線形探索のコード

def linear_search(arr, value)
  arr.each_with_index do |num, index|
    return index if num == value
  end
  return nil
end

これわざわざ名前つける必要あるのかってかんじです。

3.二分探索のコード

def binary_search(arr, n)

      arr.sort!
      min = 0 
      max = (arr.length) - 1

      while true
    mid = (min + max) / 2
      if arr[mid] > n
    max = mid
      elsif arr[mid] < n
    min = mid
      elsif arr[mid] == n
        return mid
      else
        return nil
    end
  end
end

ちなみにテストも見よう見まねで書いた。

describe "#binary" do
  it "could't find value in array" do
    expect(binary_search([1, 3, 5, 9, 11, 13, 15, 17, 19, 21, 23], 0)).to eq (nil)
  end

  it "works with sorted array" do
    expect(binary_search([1, 3, 5, 9, 11, 13, 15, 17, 19, 21, 23], 9)).to eq (3)
  end

  it "works with unsorted array" do
    expect(binary_search([15, 38, 325, 19, 211, 143, 125, 17, 19, 21, 230, 100], 21)).to eq (9)
  end
end

一番目のテストで引っかかった。。。終了条件書いていなかった。

describe "#binary" do
  it "could't find value in array" do
    expect(binary_search([1, 3, 5, 9, 11, 13, 15, 17, 19, 21, 23], 0)).to eq (nil)
  end
end

見つからなかった場合のケースです。

ようは見つからない場合どういう条件でnilを返すかを書くことが必要でした。。 ということで、見つからない時というのはどういうときかで考えると、「二分割し続けた挙句のはてに二分割の基点となるmidの値が0以下になるか,arrayの個数以上になる」とシンプルにここで切れるようにしました。

def binary_search(arr, n)

    arr.sort!
    min = 0 
    max = (arr.length) - 1

    while true
    mid = (min + max) / 2
        if arr[mid] > n
      max = mid
        elsif arr[mid] < n
      min = mid
        elsif arr[mid] == n
          return mid
        elsif mid <= 0 || mid > arr.length
          return nil
        end
    end
end

ここでまた無限ループにはまる。 上のプログラムでダメなのは、見つからない場合にループを抜けるための条件が一番下にあること。 これではnが小さい場合に二分割するというif分の二番目{ elsif arr[mid] < n }こいつに当てはまるので一生ここにハマり続けます。

def binary_search(arr, n)

    arr.sort!
    p arr
    min = 0 
    max = (arr.length) - 1

    while true
     mid = (min + max) / 2
       if mid <= 0 || mid > arr.length 
          return nil
       elsif arr[mid] > n
          max = mid
       elsif arr[mid] < n
          min = mid
       elsif arr[mid] == n
          return mid
       end
    end
end

Ruby アルゴリズム 線形探索と二分探索 - Qiita