二分探索
#アルゴリズム
Sort済みの配列のデータを検索するやつ
検索範囲のど真ん中のデータを見て大小比較をし、検索範囲を半分ずつ狭めていく
時間計算量は$ O(\log_2 n)
https://ja.wikipedia.org/wiki/二分探索
実装
JavaScript
標準ライブラリによる提供はないため、自分で実装しよう
以下は、単純な数値を用いた二分探索を行う
もちろん、比較用の関数だったり、比較演算子が使える対象であればなんでも探索可能
array 内に引数と同じ値が見つかった場合、最初の同じ値のindexを返す
同じ値がない場合、引数の値より大きな最小の値のindexを返す
code:js
function binarySearch(array, element) {
let start = 0;
let end = array.length;
while (start < end) {
const center = (start + end) >> 1;
const centerElement = arraycenter;
if (centerElement < element) {
start = center + 1;
} else {
end = center;
}
}
return start;
}
https://github.com/0b5vr/experimental-npm/blob/dev/src/algorithm/binarySearch.ts
https://github.com/0b5vr/experimental-npm/blob/dev/src/algorithm/tests/binarySearch.test.ts
Rust
Rust: Sliceのメソッドとして binary_search がある
スライス内に複数一致する値がある場合、その中のどれかが返ってくる
code:rust
fn main() {
let s = 0, 0, 1, 1, 1, 3;
let r = s.binary_search(&1);
println!("{:?}", r); // Ok(4)
}
https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search
partition_point だと、predicate使って境界を見つけられるみたいなので、こっちのほうが良いかもねえ
code:rust
fn main() {
let s = 0, 0, 1, 1, 1, 3;
let i = s.partition_point(|&x| x < 1);
println!("{:?}", i); // 2
}
https://doc.rust-lang.org/std/primitive.slice.html#method.partition_point
C++
Rust同様、イテレータに対して binary_search と partition_point が用意されていそう
https://cpprefjp.github.io/reference/algorithm/binary_search.html
https://cpprefjp.github.io/reference/algorithm/partition_point.html