This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
86
unikernel/duniverse/base/src/binary_search.mli
Normal file
86
unikernel/duniverse/base/src/binary_search.mli
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
(** Functions for performing binary searches over ordered sequences given
|
||||
[length] and [get] functions.
|
||||
|
||||
These functions can be specialized and added to a data structure using the functors
|
||||
supplied in {{!Base.Binary_searchable}[Binary_searchable]} and described in
|
||||
{{!Base.Binary_searchable_intf}[Binary_searchable_intf]}.
|
||||
|
||||
{2:examples Examples}
|
||||
|
||||
Below we assume that the functions [get], [length] and [compare] are in scope:
|
||||
|
||||
{[
|
||||
(* Find the index of an element [e] in [t] *)
|
||||
binary_search t ~get ~length ~compare `First_equal_to e;
|
||||
|
||||
(* Find the index where an element [e] should be inserted *)
|
||||
binary_search t ~get ~length ~compare `First_greater_than_or_equal_to e;
|
||||
|
||||
(* Find the index in [t] where all elements to the left are less than [e] *)
|
||||
binary_search_segmented t ~get ~length ~segment_of:(fun e' ->
|
||||
if compare e' e <= 0 then `Left else `Right) `First_on_right
|
||||
]} *)
|
||||
|
||||
open! Import
|
||||
|
||||
(** [binary_search ?pos ?len t ~length ~get ~compare which elt] takes [t] that is sorted
|
||||
in increasing order according to [compare], where [compare] and [elt] divide [t] into
|
||||
three (possibly empty) segments:
|
||||
|
||||
{v
|
||||
| < elt | = elt | > elt |
|
||||
v}
|
||||
|
||||
[binary_search] returns the index in [t] of an element on the boundary of segments
|
||||
as specified by [which]. See the diagram below next to the [which] variants.
|
||||
|
||||
By default, [binary_search] searches the entire [t]. One can supply [?pos] or
|
||||
[?len] to search a slice of [t].
|
||||
|
||||
[binary_search] does not check that [compare] orders [t], and behavior is
|
||||
unspecified if [compare] doesn't order [t]. Behavior is also unspecified if
|
||||
[compare] mutates [t]. *)
|
||||
val binary_search
|
||||
: ?pos:int
|
||||
-> ?len:int
|
||||
-> 't
|
||||
-> length:('t -> int)
|
||||
-> get:('t -> int -> 'elt)
|
||||
-> compare:('elt -> 'key -> int)
|
||||
-> [ `Last_strictly_less_than (** {v | < elt X | v} *)
|
||||
| `Last_less_than_or_equal_to (** {v | <= elt X | v} *)
|
||||
| `Last_equal_to (** {v | = elt X | v} *)
|
||||
| `First_equal_to (** {v | X = elt | v} *)
|
||||
| `First_greater_than_or_equal_to (** {v | X >= elt | v} *)
|
||||
| `First_strictly_greater_than (** {v | X > elt | v} *)
|
||||
]
|
||||
-> 'key
|
||||
-> int option
|
||||
|
||||
(** [binary_search_segmented ?pos ?len t ~length ~get ~segment_of which] takes a
|
||||
[segment_of] function that divides [t] into two (possibly empty) segments:
|
||||
|
||||
{v
|
||||
| segment_of elt = `Left | segment_of elt = `Right |
|
||||
v}
|
||||
|
||||
[binary_search_segmented] returns the index of the element on the boundary of the
|
||||
segments as specified by [which]: [`Last_on_left] yields the index of the last
|
||||
element of the left segment, while [`First_on_right] yields the index of the first
|
||||
element of the right segment. It returns [None] if the segment is empty.
|
||||
|
||||
By default, [binary_search] searches the entire [t]. One can supply [?pos] or
|
||||
[?len] to search a slice of [t].
|
||||
|
||||
[binary_search_segmented] does not check that [segment_of] segments [t] as in the
|
||||
diagram, and behavior is unspecified if [segment_of] doesn't segment [t]. Behavior
|
||||
is also unspecified if [segment_of] mutates [t]. *)
|
||||
val binary_search_segmented
|
||||
: ?pos:int
|
||||
-> ?len:int
|
||||
-> 't
|
||||
-> length:('t -> int)
|
||||
-> get:('t -> int -> 'elt)
|
||||
-> segment_of:('elt -> [ `Left | `Right ])
|
||||
-> [ `Last_on_left | `First_on_right ]
|
||||
-> int option
|
||||
Loading…
Add table
Add a link
Reference in a new issue