new files

This commit is contained in:
Ingy döt Net 2013-04-10 12:38:42 -07:00
parent 3af7344581
commit 86c034bb8b
1364 changed files with 21352 additions and 0 deletions

View file

@ -0,0 +1,140 @@
A binary search divides a range of values into halves, and continues to narrow down the field of search until the unknown value is found. It is the classic example of a "divide and conquer" algorithm.
As an analogy, consider the children's game "[[Guess the number/With feedback|guess a number]]." The scorer has a secret number, and will only tell the player if their guessed number is higher than, lower than, or equal to the secret number. The player then uses this information to guess a new number.
As the player, an optimal strategy for the general case is to start by choosing the range's midpoint as the guess, and then asking whether the guess was higher, lower, or equal to the secret number. If the guess was too high, one would select the point exactly between the range midpoint and the beginning of the range. If the original guess was too low, one would ask about the point exactly between the range midpoint and the end of the range. This process repeats until one has reached the secret number.
'''The Task'''
Given the starting point of a range, the ending point of a range, and the "secret value", implement a binary search through a sorted integer array for a certain number. Implementations can be recursive or iterative (both if you can). Print out whether or not the number was in the array afterwards. If it was, print the index also.
There are several binary search algorithms commonly seen. They differ by how they treat multiple values equal to the given value, and whether they indicate whether the element was found or not. For completeness we will present pseudocode for all of them.
All of the following code examples use an "inclusive" upper bound (i.e. <code>high = N-1</code> initially). Any of the examples can be converted into an equivalent example using "exclusive" upper bound (i.e. <code>high = N</code> initially) by making the following simple changes (which simply increase <code>high</code> by 1):
* change <code>high = N-1</code> to <code>high = N</code>
* change <code>high = mid-1</code> to <code>high = mid</code>
* (for recursive algorithm) change <code>if (high < low)</code> to <code>if (high <= low)</code>
* (for iterative algorithm) change <code>while (low <= high)</code> to <code>while (low < high)</code>
; Traditional algorithm
The algorithms are as follows (from [[wp:Binary search|Wikipedia]]). The algorithms return the index of some element that equals the given value (if there are multiple such elements, it returns some arbitrary one). It is also possible, when the element is not found, to return the "insertion point" for it (the index that the value would have if it were inserted into the array).
'''Recursive Pseudocode''':
// initially called with low = 0, high = N-1
BinarySearch(A[0..N-1], value, low, high) {
// invariants: value > A[i] for all i < low
value < A[i] for all i > high
if (high < low)
return not_found // value would be inserted at index "low"
mid = (low + high) / 2
if (A[mid] > value)
return BinarySearch(A, value, low, mid-1)
else if (A[mid] < value)
return BinarySearch(A, value, mid+1, high)
else
return mid
}
'''Iterative Pseudocode''':
BinarySearch(A[0..N-1], value) {
low = 0
high = N - 1
while (low <= high) {
// invariants: value > A[i] for all i < low
value < A[i] for all i > high
mid = (low + high) / 2
if (A[mid] > value)
high = mid - 1
else if (A[mid] < value)
low = mid + 1
else
return mid
}
return not_found // value would be inserted at index "low"
}
; Leftmost insertion point
The following algorithms return the leftmost place where the given element can be correctly inserted (and still maintain the sorted order). This is the lower (inclusive) bound of the range of elements that are equal to the given value (if any). Equivalently, this is the lowest index where the element is greater than or equal to the given value (since if it were any lower, it would violate the ordering), or 1 past the last index if such an element does not exist. This algorithm does not determine if the element is actually found. This algorithm only requires one comparison per level.
'''Recursive Pseudocode''':
// initially called with low = 0, high = N - 1
BinarySearch_Left(A[0..N-1], value, low, high) {
// invariants: value > A[i] for all i < low
value <= A[i] for all i > high
if (high < low)
return low
mid = (low + high) / 2
if (A[mid] >= value)
return BinarySearch_Left(A, value, low, mid-1)
else
return BinarySearch_Left(A, value, mid+1, high)
}
'''Iterative Pseudocode''':
BinarySearch_Left(A[0..N-1], value) {
low = 0
high = N - 1
while (low <= high) {
// invariants: value > A[i] for all i < low
value <= A[i] for all i > high
mid = (low + high) / 2
if (A[mid] >= value)
high = mid - 1
else
low = mid + 1
}
return low
}
; Rightmost insertion point
The following algorithms return the rightmost place where the given element can be correctly inserted (and still maintain the sorted order). This is the upper (exclusive) bound of the range of elements that are equal to the given value (if any). Equivalently, this is the lowest index where the element is greater than the given value, or 1 past the last index if such an element does not exist. This algorithm does not determine if the element is actually found. This algorithm only requires one comparison per level. Note that these algorithms are almost exactly the same as the leftmost-insertion-point algorithms, except for how the inequality treats equal values.
'''Recursive Pseudocode''':
// initially called with low = 0, high = N - 1
BinarySearch_Right(A[0..N-1], value, low, high) {
// invariants: value >= A[i] for all i < low
value < A[i] for all i > high
if (high < low)
return low
mid = (low + high) / 2
if (A[mid] > value)
return BinarySearch_Right(A, value, low, mid-1)
else
return BinarySearch_Right(A, value, mid+1, high)
}
'''Iterative Pseudocode''':
BinarySearch_Right(A[0..N-1], value) {
low = 0
high = N - 1
while (low <= high) {
// invariants: value >= A[i] for all i < low
value < A[i] for all i > high
mid = (low + high) / 2
if (A[mid] > value)
high = mid - 1
else
low = mid + 1
}
return low
}
;Extra credit
Make sure it does not have overflow bugs.
The line in the pseudocode above to calculate the mean of two integers:
<pre>mid = (low + high) / 2</pre>
could produce the wrong result in some programming languages when used with a bounded integer type, if the addition causes an overflow. (This can occur if the array size is greater than half the maximum integer value.) If signed integers are used, and <code>low + high</code> overflows, it becomes a negative number, and dividing by 2 will still result in a negative number. Indexing an array with a negative number could produce an out-of-bounds exception, or other undefined behavior. If unsigned integers are used, an overflow will result in losing the largest bit, which will produce the wrong result.
One way to fix it is to manually add half the range to the low number:
<pre>mid = low + (high - low) / 2</pre>
Even though this is mathematically equivalent to the above, it is not susceptible to overflow.
Another way for signed integers, possibly faster, is the following:
<pre>mid = (low + high) >>> 1</pre>
where <code> >>> </code> is the logical right shift operator. The reason why this works is that, for signed integers, even though it overflows, when viewed as an unsigned number, the value is still the correct sum. To divide an unsigned number by 2, simply do a logical right shift.
'''References:'''<br>
:* C.f: [[Guess the number/With Feedback (Player)]]
:* [[wp:Binary search algorithm]]
:* [http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken].

View file

@ -0,0 +1,4 @@
---
category:
- Recursion
note: Classic CS problems and programs

View file

@ -0,0 +1,61 @@
(defun defarray (name size initial-element)
(cons name
(compress1 name
(cons (list :HEADER
:DIMENSIONS (list size)
:MAXIMUM-LENGTH (1+ size)
:DEFAULT initial-element
:NAME name)
nil))))
(defconst *dim* 100000)
(defun array-name (array)
(first array))
(defun set-at (array i val)
(cons (array-name array)
(aset1 (array-name array)
(cdr array)
i
val)))
(defun populate-array-ordered (array n)
(if (zp n)
array
(populate-array-ordered (set-at array
(- *dim* n)
(- *dim* n))
(1- n))))
(include-book "arithmetic-3/top" :dir :system)
(defun binary-search-r (needle haystack low high)
(declare (xargs :measure (nfix (1+ (- high low)))))
(let* ((mid (floor (+ low high) 2))
(current (aref1 (array-name haystack)
(cdr haystack)
mid)))
(cond ((not (and (natp low) (natp high))) nil)
((= current needle)
mid)
((zp (1+ (- high low))) nil)
((> current needle)
(binary-search-r needle
haystack
low
(1- mid)))
(t (binary-search-r needle
haystack
(1+ mid)
high)))))
(defun binary-search (needle haystack)
(binary-search-r needle haystack 0
(maximum-length (array-name haystack)
(cdr haystack))))
(defun test-bsearch (needle)
(binary-search needle
(populate-array-ordered
(defarray 'haystack *dim* 0)
*dim*)))

View file

@ -0,0 +1,8 @@
function binary_search(array, value, left, right, middle) {
if (right < left) return 0
middle = int((right + left) / 2)
if (value == array[middle]) return 1
if (value < array[middle])
return binary_search(array, value, left, middle - 1)
return binary_search(array, value, middle + 1, right)
}

View file

@ -0,0 +1,9 @@
function binary_search(array, value, left, right, middle) {
while (left <= right) {
middle = int((right + left) / 2)
if (value == array[middle]) return 1
if (value < array[middle]) right = middle - 1
else left = middle + 1
}
return 0
}

View file

@ -0,0 +1,54 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Recursive_Binary_Search is
Not_Found : exception;
generic
type Index is range <>;
type Element is private;
type Array_Of_Elements is array (Index range <>) of Element;
with function "<" (L, R : Element) return Boolean is <>;
function Search (Container : Array_Of_Elements; Value : Element) return Index;
function Search (Container : Array_Of_Elements; Value : Element) return Index is
Mid : Index;
begin
if Container'Length > 0 then
Mid := (Container'First + Container'Last) / 2;
if Value < Container (Mid) then
if Container'First /= Mid then
return Search (Container (Container'First..Mid - 1), Value);
end if;
elsif Container (Mid) < Value then
if Container'Last /= Mid then
return Search (Container (Mid + 1..Container'Last), Value);
end if;
else
return Mid;
end if;
end if;
raise Not_Found;
end Search;
type Integer_Array is array (Positive range <>) of Integer;
function Find is new Search (Positive, Integer, Integer_Array);
procedure Test (X : Integer_Array; E : Integer) is
begin
New_Line;
for I in X'Range loop
Put (Integer'Image (X (I)));
end loop;
Put (" contains" & Integer'Image (E) & " at" & Integer'Image (Find (X, E)));
exception
when Not_Found =>
Put (" does not contain" & Integer'Image (E));
end Test;
begin
Test ((2, 4, 6, 8, 9), 2);
Test ((2, 4, 6, 8, 9), 1);
Test ((2, 4, 6, 8, 9), 8);
Test ((2, 4, 6, 8, 9), 10);
Test ((2, 4, 6, 8, 9), 9);
Test ((2, 4, 6, 8, 9), 5);
end Test_Recursive_Binary_Search;

View file

@ -0,0 +1,56 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Binary_Search is
Not_Found : exception;
generic
type Index is range <>;
type Element is private;
type Array_Of_Elements is array (Index range <>) of Element;
with function "<" (L, R : Element) return Boolean is <>;
function Search (Container : Array_Of_Elements; Value : Element) return Index;
function Search (Container : Array_Of_Elements; Value : Element) return Index is
Low : Index := Container'First;
High : Index := Container'Last;
Mid : Index;
begin
if Container'Length > 0 then
loop
Mid := (Low + High) / 2;
if Value < Container (Mid) then
exit when Low = Mid;
High := Mid - 1;
elsif Container (Mid) < Value then
exit when High = Mid;
Low := Mid + 1;
else
return Mid;
end if;
end loop;
end if;
raise Not_Found;
end Search;
type Integer_Array is array (Positive range <>) of Integer;
function Find is new Search (Positive, Integer, Integer_Array);
procedure Test (X : Integer_Array; E : Integer) is
begin
New_Line;
for I in X'Range loop
Put (Integer'Image (X (I)));
end loop;
Put (" contains" & Integer'Image (E) & " at" & Integer'Image (Find (X, E)));
exception
when Not_Found =>
Put (" does not contain" & Integer'Image (E));
end Test;
begin
Test ((2, 4, 6, 8, 9), 2);
Test ((2, 4, 6, 8, 9), 1);
Test ((2, 4, 6, 8, 9), 8);
Test ((2, 4, 6, 8, 9), 10);
Test ((2, 4, 6, 8, 9), 9);
Test ((2, 4, 6, 8, 9), 5);
end Test_Binary_Search;

View file

@ -0,0 +1,17 @@
FUNCTION binary_search ( array() AS Integer, value AS Integer, lo AS Integer, hi AS Integer) AS Integer
DIM middle AS Integer
IF hi < lo THEN
binary_search = 0
ELSE
middle = (hi + lo) / 2
SELECT CASE value
CASE IS < array(middle)
binary_search = binary_search(array(), value, lo, middle-1)
CASE IS > array(middle)
binary_search = binary_search(array(), value, middle+1, hi)
CASE ELSE
binary_search = middle
END SELECT
END IF
END FUNCTION

View file

@ -0,0 +1,17 @@
FUNCTION binary_search ( array() AS Integer, value AS Integer, lo AS Integer, hi AS Integer) AS Integer
DIM middle AS Integer
WHILE lo <= hi
middle = (hi + lo) / 2
SELECT CASE value
CASE IS < array(middle)
hi = middle - 1
CASE IS > array(middle)
lo = middle + 1
CASE ELSE
binary_search = middle
EXIT FUNCTION
END SELECT
WEND
binary_search = 0
END FUNCTION

View file

@ -0,0 +1,23 @@
SUB search (array() AS Integer, value AS Integer)
DIM idx AS Integer
idx = binary_search(array(), value, LBOUND(array), UBOUND(array))
PRINT "Value "; value;
IF idx < 1 THEN
PRINT " not found"
ELSE
PRINT " found at index "; idx
END IF
END SUB
DIM test(1 TO 10) AS Integer
DIM i AS Integer
DATA 2, 3, 5, 6, 8, 10, 11, 15, 19, 20
FOR i = 1 TO 10 ' Fill the test array
READ test(i)
NEXT i
search test(), 4
search test(), 8
search test(), 20

View file

@ -0,0 +1,36 @@
/* http://www.solipsys.co.uk/b_search/spec.htm */
typedef int Object;
int cmpObject(Object* pa, Object *pb)
{
Object a = *pa;
Object b = *pb;
if (a < b) return -1;
if (a == b) return 0;
if (a > b) return 1;
assert(0);
}
int bsearch(Object Array[], int n, Object *KeyPtr,
int (*cmp)(Object *, Object *),
int NotFound)
{
unsigned left = 1, right = n; /* `unsigned' to avoid overflow in `(left + right)/2' */
if ( ! (Array && n > 0 && KeyPtr && cmp))
return NotFound; /* invalid input or empty array */
while (left < right)
{
/* invariant: a[left] <= *KeyPtr <= a[right] or *KeyPtr not in Array */
unsigned m = (left + right) / 2; /*NOTE: *intentionally* truncate for odd sum */
if (cmp(Array + m, KeyPtr) < 0)
left = m + 1; /* a[m] < *KeyPtr <= a[right] or *KeyPtr not in Array */
else
/* assert(right != m) or infinite loop possible */
right = m; /* a[left] <= *KeyPtr <= a[m] or *KeyPtr not in Array */
}
/* assert(left == right) */
return (cmp(Array + right, KeyPtr) == 0) ? right : NotFound;
}

View file

@ -0,0 +1,38 @@
#define DUMMY -1 /* dummy element of array (to adjust indexing from 1..n) */
int main(void)
{
Object a[] = {DUMMY, 0, 1, 1, 2, 5}; /* allowed indices from 1 to n including */
int n = sizeof(a)/sizeof(*a) - 1;
const int NotFound = -1;
/* key not in Array */
Object key = 4;
assert(NotFound == bsearch(a, n, &key, cmpObject, NotFound));
key = DUMMY;
assert(NotFound == bsearch(a, n, &key, cmpObject, NotFound));
key = 7;
assert(NotFound == bsearch(a, n, &key, cmpObject, NotFound));
/* all possible `n' and `k' for `a' array */
int k;
key = 10; /* not in `a` array */
for (n = 0; n <= sizeof(a)/sizeof(*a) - 1; ++n)
for (k = n; k>=1; --k) {
int index = bsearch(a, n, &a[k], cmpObject, NotFound);
assert(index == k || (k==3 && index == 2) || n == 0); /* for equal `1's */
assert(NotFound == bsearch(a, n, &key, cmpObject, NotFound));
}
n = sizeof(a)/sizeof(*a) - 1;
/* NULL array */
assert(NotFound == bsearch(NULL, n, &key, cmpObject, NotFound));
/* NULL &key */
assert(NotFound == bsearch(a, n, NULL, cmpObject, NotFound));
/* NULL cmpObject */
assert(1 == bsearch(a, n, &a[1], cmpObject, NotFound));
assert(NotFound == bsearch(a, n, &a[1], NULL, NotFound));
printf("OK\n");
return 0;
}

View file

@ -0,0 +1,21 @@
#include <stdlib.h> /* for bsearch */
#include <stdio.h>
int intcmp(const void *a, const void *b)
{
/* this is only correct if it doesn't overflow */
return *(const int *)a - *(const int *)b;
}
int main()
{
int nums[5] = {2, 3, 5, 6, 8};
int desired = 6;
int *ptr = bsearch(&desired, nums, 5, sizeof(int), intcmp);
if (ptr == NULL)
printf("not found\n");
else
printf("index = %d\n", ptr - nums);
return 0;
}

View file

@ -0,0 +1,16 @@
(defn bsearch
([coll t]
(bsearch coll 0 (dec (count coll)) t))
([coll l u t]
(if (> l u) -1
(let [m (quot (+ l u) 2) mth (nth coll m)]
(cond
; the middle element is greater than t
; so search the lower half
(> mth t) (recur coll l (dec m) t)
; the middle element is less than t
; so search the upper half
(< mth t) (recur coll (inc m) u t)
; we've found our target
; so return its index
(= mth t) m)))))

View file

@ -0,0 +1,16 @@
binsearch = (arr, k) ->
low = 0
high = arr.length - 1
while low <= high
mid = Math.floor (low + high) / 2
return mid if arr[mid] == k
if arr[mid] < k
low = mid + 1
else
high = mid - 1
null
arr = [1,3,5,7,9,11]
for i in [0..12]
pos = binsearch arr, i
console.log "found #{i} at pos #{pos}" if pos?

View file

@ -0,0 +1,27 @@
%% Task: Binary Search algorithm
%% Author: Abhay Jain
-module(searching_algorithm).
-export([start/0]).
start() ->
List = [1,2,3],
binary_search(List, 5, 1, length(List)).
binary_search(List, Value, Low, High) ->
if Low > High ->
io:format("Number ~p not found~n", [Value]),
not_found;
true ->
Mid = (Low + High) div 2,
MidNum = lists:nth(Mid, List),
if MidNum > Value ->
binary_search(List, Value, Low, Mid-1);
MidNum < Value ->
binary_search(List, Value, Mid+1, High);
true ->
io:format("Number ~p found at index ~p", [Value, Mid]),
Mid
end
end.

View file

@ -0,0 +1,31 @@
defer (compare)
' - is (compare) \ default to numbers
: cstr-compare ( cstr1 cstr2 -- <=> ) \ counted strings
swap count rot count compare ;
: mid ( u l -- mid ) tuck - 2/ -cell and + ;
: bsearch ( item upper lower -- where found? )
rot >r
begin 2dup >
while 2dup mid
dup @ r@ (compare)
dup
while 0<
if nip cell+ ( upper mid+1 )
else rot drop swap ( mid lower )
then
repeat drop nip nip true
else max ( insertion-point ) false
then
r> drop ;
create test 2 , 4 , 6 , 9 , 11 , 99 ,
: probe ( n -- ) test 5 cells bounds bsearch . @ . cr ;
1 probe \ 0 2
2 probe \ -1 2
3 probe \ 0 4
10 probe \ 0 11
11 probe \ -1 11
12 probe \ 0 99

View file

@ -0,0 +1,18 @@
recursive function binarySearch_R (a, value) result (bsresult)
real, intent(in) :: a(:), value
integer :: bsresult, mid
mid = size(a)/2 + 1
if (size(a) == 0) then
bsresult = 0 ! not found
else if (a(mid) > value) then
bsresult= binarySearch_R(a(:mid-1), value)
else if (a(mid) < value) then
bsresult = binarySearch_R(a(mid+1:), value)
if (bsresult /= 0) then
bsresult = mid + bsresult
end if
else
bsresult = mid ! SUCCESS!!
end if
end function binarySearch_R

View file

@ -0,0 +1,23 @@
function binarySearch_I (a, value)
integer :: binarySearch_I
real, intent(in), target :: a(:)
real, intent(in) :: value
real, pointer :: p(:)
integer :: mid, offset
p => a
binarySearch_I = 0
offset = 0
do while (size(p) > 0)
mid = size(p)/2 + 1
if (p(mid) > value) then
p => p(:mid-1)
else if (p(mid) < value) then
offset = offset + mid
p => p(mid+1:)
else
binarySearch_I = offset + mid ! SUCCESS!!
return
end if
end do
end function binarySearch_I

View file

@ -0,0 +1,12 @@
func binarySearch(a []float64, value float64, low int, high int) int {
if high < low {
return -1
}
mid := (low + high) / 2
if a[mid] > value {
return binarySearch(a, value, low, mid-1)
} else if a[mid] < value {
return binarySearch(a, value, mid+1, high)
}
return mid
}

View file

@ -0,0 +1,15 @@
func binarySearch(a []float64, value float64) int {
low := 0
high := len(a) - 1
for low <= high {
mid := (low + high) / 2
if a[mid] > value {
high = mid - 1
} else if a[mid] < value {
low = mid + 1
} else {
return mid
}
}
return -1
}

View file

@ -0,0 +1,5 @@
import "sort"
//...
sort.SearchInts([]int{0,1,4,5,6,7,8,9}, 6) // evaluates to 4

View file

@ -0,0 +1,9 @@
binarySearch :: Integral a => (a -> Ordering) -> (a, a) -> Maybe a
binarySearch p (low,high)
| high < low = Nothing
| otherwise =
let mid = (low + high) `div` 2 in
case p mid of
LT -> binarySearch p (low, mid-1)
GT -> binarySearch p (mid+1, high)
EQ -> Just mid

View file

@ -0,0 +1,5 @@
import Data.Array
binarySearchArray :: (Ix i, Integral i, Ord e) => Array i e -> e -> Maybe i
binarySearchArray a x = binarySearch p (bounds a) where
p m = x `compare` (a ! m)

View file

@ -0,0 +1,27 @@
...
//check will be the number we are looking for
//nums will be the array we are searching through
public static int binarySearch(int[] nums, int check){
int hi = nums.length - 1;
int lo = 0;
while(hi >= lo){
guess = lo + ((hi - lo) / 2);
if(nums[guess] > check){
hi = guess - 1;
}else if(nums[guess] < check){
lo = guess + 1;
}else{
return guess;
}
}
return -1;
}
public static void main(String[] args){
int[] searchMe;
int someNumber;
...
int index = binarySearch(searchMe, someNumber);
System.out.println(someNumber + ((index == -1) ? " is not in the array" : (" is at index " + index)));
...
}

View file

@ -0,0 +1,21 @@
public static void main(String[] args){
int[] searchMe;
int someNumber;
...
int index = binarySearch(searchMe, someNumber, 0, searchMe.length);
System.out.println(someNumber + ((index == -1) ? " is not in the array" : (" is at index " + index)));
...
}
public static int binarySearch(int[] nums, int check, int lo, int hi){
if(hi < lo){
return -1; //impossible index for "not found"
}
int guess = (hi + lo) / 2;
if(nums[guess] > check){
return binarySearch(nums, check, lo, guess - 1);
}else if(nums[guess]<check){
return binarySearch(nums, check, guess + 1, hi);
}
return guess;
}

View file

@ -0,0 +1,8 @@
import java.util.Arrays;
int index = Arrays.binarySearch(array, thing);
int index = Arrays.binarySearch(array, startIndex, endIndex, thing);
// for objects, also optionally accepts an additional comparator argument:
int index = Arrays.binarySearch(array, thing, comparator);
int index = Arrays.binarySearch(array, startIndex, endIndex, thing, comparator);

View file

@ -0,0 +1,4 @@
import java.util.Collections;
int index = Collections.binarySearch(list, thing);
int index = Collections.binarySearch(list, thing, comparator);

View file

@ -0,0 +1,11 @@
function binary_search_recursive(a, value, lo, hi) {
if (hi < lo)
return null;
var mid = Math.floor((lo+hi)/2);
if (a[mid] > value)
return binary_search_recursive(a, value, lo, mid-1);
else if (a[mid] < value)
return binary_search_recursive(a, value, mid+1, hi);
else
return mid;
}

View file

@ -0,0 +1,14 @@
function binary_search_iterative(a, value) {
lo = 0;
hi = a.length - 1;
while (lo <= hi) {
var mid = Math.floor((lo+hi)/2);
if (a[mid] > value)
hi = mid - 1;
else if (a[mid] < value)
lo = mid + 1;
else
return mid;
}
return null;
}

View file

@ -0,0 +1,14 @@
function binarySearch (list,value)
local low = 1
local high = #list
local mid = 0
while low <= high do
mid = math.floor((low+high)/2)
if list[mid] > value then high = mid - 1
else if list[mid] < value then low = mid + 1
else return mid
end
end
end
return false
end

View file

@ -0,0 +1,9 @@
function binarySearch (list, value)
local function search(low, high)
local mid = math.floor((low+high)/2)
if list[mid] > value then return search(low,mid-1) end
if list[mid] < value then return search(mid+1,high) end
return mid
end
return search(1,#list)
end

View file

@ -0,0 +1,19 @@
function binary_search( $array, $secret, $start, $end )
{
do
{
$guess = (int)($start + ( ( $end - $start ) / 2 ));
if ( $array[$guess] > $secret )
$end = $guess;
if ( $array[$guess] < $secret )
$start = $guess;
if ( $end < $start)
return -1;
} while ( $array[$guess] != $secret );
return $guess;
}

View file

@ -0,0 +1,15 @@
function binary_search( $array, $secret, $start, $end )
{
$guess = (int)($start + ( ( $end - $start ) / 2 ));
if ( $end < $start)
return -1;
if ( $array[$guess] > $secret )
return (binary_search( $array, $secret, $start, $guess ));
if ( $array[$guess] < $secret )
return (binary_search( $array, $secret, $guess, $end ) );
return $guess;
}

View file

@ -0,0 +1,15 @@
sub binary_search {
($array_ref, $value, $left, $right) = @_;
while ($left <= $right) {
$middle = ($right + $left) / 2;
if ($array_ref->[$middle] == $value) {
return 1;
}
if ($value < $array_ref->[$middle]) {
$right = $middle - 1;
} else {
$left = $middle + 1;
}
}
return 0;
}

View file

@ -0,0 +1,15 @@
sub binary_search {
($array_ref, $value, $left, $right) = @_;
if ($right < $left) {
return 0;
}
$middle = ($right + $left) / 2;
if ($array_ref->[$middle] == $value) {
return 1;
}
if ($value < $array_ref->[$middle]) {
binary_search($array_ref, $value, $left, $middle - 1);
} else {
binary_search($array_ref, $value, $middle + 1, $right);
}
}

View file

@ -0,0 +1,8 @@
(de recursiveSearch (Val Lst Len)
(unless (=0 Len)
(let (N (inc (/ Len 2)) L (nth Lst N))
(cond
((= Val (car L)) Val)
((> Val (car L))
(recursiveSearch Val (cdr L) (- Len N)) )
(T (recursiveSearch Val Lst (dec N))) ) ) ) )

View file

@ -0,0 +1,11 @@
(de iterativeSearch (Val Lst Len)
(use (N L)
(loop
(T (=0 Len))
(setq
N (inc (/ Len 2))
L (nth Lst N) )
(T (= Val (car L)) Val)
(if (> Val (car L))
(setq Lst (cdr L) Len (- Len N))
(setq Len (dec N)) ) ) ) )

View file

@ -0,0 +1,9 @@
def binary_search(l, value):
low = 0
high = len(l)-1
while low <= high:
mid = (low+high)//2
if l[mid] > value: high = mid-1
elif l[mid] < value: low = mid+1
else: return mid
return -1

View file

@ -0,0 +1,10 @@
def binary_search(l, value, low = 0, high = -1):
if not l: return -1
if(high == -1): high = len(l)-1
if low == high:
if l[low] == value: return low
else: return -1
mid = (low+high)//2
if l[mid] > value: return binary_search(l, value, low, mid-1)
elif l[mid] < value: return binary_search(l, value, mid+1, high)
else: return mid

View file

@ -0,0 +1,8 @@
index = bisect.bisect_left(list, item) # leftmost insertion point
index = bisect.bisect_right(list, item) # rightmost insertion point
index = bisect.bisect(list, item) # same as bisect_right
# same as above but actually insert the item into the list at the given place:
bisect.insort_left(list, item)
bisect.insort_right(list, item)
bisect.insort(list, item)

View file

@ -0,0 +1,13 @@
BinSearch <- function(A, value, low, high) {
if ( high < low ) {
return(NULL)
} else {
mid <- floor((low + high) / 2)
if ( A[mid] > value )
BinSearch(A, value, low, mid-1)
else if ( A[mid] < value )
BinSearch(A, value, mid+1, high)
else
mid
}
}

View file

@ -0,0 +1,15 @@
IterBinSearch <- function(A, value) {
low = 1
high = length(A)
i = 0
while ( low <= high ) {
mid <- floor((low + high)/2)
if ( A[mid] > value )
high <- mid - 1
else if ( A[mid] < value )
low <- mid + 1
else
return(mid)
}
NULL
}

View file

@ -0,0 +1,4 @@
a <- 1:100
IterBinSearch(a, 50)
BinSearch(a, 50, 1, length(a)) # output 50
IterBinSearch(a, 101) # outputs NULL

View file

@ -0,0 +1,34 @@
/*REXX program finds a value in a list using a recursive binary search. */
@=' 11 17 29 37 41 59 67 71 79 97 101 107 127 137 149',
'163 179 191 197 223 227 239 251 269 277 281 307 311 331 347',
'367 379 397 419 431 439 457 461 479 487 499 521 541 557 569',
'587 599 613 617 631 641 659 673 701 719 727 739 751 757 769',
'787 809 821 827 853 857 877 881 907 929 937 967 991 1009'
/*(above) list of strong primes.*/
parse arg ? . /*get a number the user specified*/
if ?=='' then do
say; say '*** error! *** no arg specified.'; say
exit 13
end
low = 1
high = words(@)
avg=(word(@,1)+word(@,high))/2
loc = binarySearch(low,high)
if loc==-1 then do
say ? "wasn't found in the list."
exit /*stick a fork in it, we're done.*/
end
else say ? 'is in the list, its index is:' loc
say
say 'arithmetic mean of the' high "values=" avg
exit /*stick a fork in it, we're done.*/
/*─────────────────────────────────────BINARYSEARCH subroutine──────────*/
binarySearch: procedure expose @ ?; parse arg low,high
if high<low then return -1
mid=(low+high)%2
y=word(@,mid)
if ?=y then return mid
if y>? then return binarySearch(low,mid-1)
return binarySearch(mid+1,high)

View file

@ -0,0 +1,31 @@
/*REXX program finds a value in a list using an iterative binary search.*/
@=' 3 7 13 19 23 31 43 47 61 73 83 89 103 109 113 131',
'139 151 167 181 193 199 229 233 241 271 283 293 313 317 337 349',
'353 359 383 389 401 409 421 433 443 449 463 467 491 503 509 523',
'547 571 577 601 619 643 647 661 677 683 691 709 743 761 773 797',
'811 823 829 839 859 863 883 887 911 919 941 953 971 983 1013'
/*(above) list of weak primes. */
parse arg ? . /*get a number the user specified*/
if ?=='' then do
say; say '*** error! *** no arg specified.'; say
exit 13
end
low = 1
high = words(@)
say 'arithmetic mean of the' high "values=" (word(@,1)+word(@,high))/2
say
do while low<=high; mid=(low+high)%2; y=word(@,mid)
if ?=y then do
say ? 'is in the list, its index is:' mid
exit /*stick a fork in it, we're done.*/
end
if y>? then high=mid-1
else low=mid+1
end /*while*/
say ? "wasn't found in the list."
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,13 @@
#lang racket
(define (binary-search x v)
; loop : index index -> index or #f
; return i s.t. l<=i<h and v[i]=x
(define (loop l h)
(cond [(>= l h) #f]
[else (define m (quotient (+ l h) 2))
(define y (vector-ref v m))
(cond
[(> y x) (loop l (- m 1))]
[(< y x) (loop (+ m 1) h)]
[else m])]))
(loop 0 (vector-length v)))

View file

@ -0,0 +1,24 @@
class Array
def binary_search(val, low=0, high=(length - 1))
return nil if high < low
mid = (low + high) / 2
case
when self[mid] > val then binary_search(val, low, mid-1)
when self[mid] < val then binary_search(val, mid+1, high)
else mid
end
end
end
def do_a_binary_search(val, ary, method)
i = ary.send(method, val)
if i
puts "found #{val} at index #{i}: #{ary[i]}"
else
puts "#{val} not found in array"
end
end
ary = [0,1,4,5,6,7,8,9,12,26,45,67,78,90,98,123,211,234,456,769,865,2345,3215,14345,24324]
do_a_binary_search(45, ary, :binary_search)
do_a_binary_search(42, ary, :binary_search)

View file

@ -0,0 +1,18 @@
class Array
def binary_search_iterative(val)
low, high = 0, length - 1
while low <= high
mid = (low + high) / 2
case
when self[mid] > val then high = mid - 1
when self[mid] < val then low = mid + 1
else return mid
end
end
nil
end
end
ary = [0,1,4,5,6,7,8,9,12,26,45,67,78,90,98,123,211,234,456,769,865,2345,3215,14345,24324]
do_a_binary_search(45, ary, :binary_search_iterative)
do_a_binary_search(42, ary, :binary_search_iterative)

View file

@ -0,0 +1,9 @@
def binarySearch[A <% Ordered[A]](a: IndexedSeq[A], v: A) = {
def recurse(low: Int, high: Int): Option[Int] = (low + high) / 2 match {
case _ if high < low => None
case mid if a(mid) > v => recurse(low, mid - 1)
case mid if a(mid) < v => recurse(mid + 1, high)
case mid => Some(mid)
}
recurse(0, a.size - 1)
}

View file

@ -0,0 +1,11 @@
(define (binary-search value vector)
(let helper ((low 0)
(high (- (vector-length vector) 1)))
(if (< high low)
#f
(let ((middle (quotient (+ low high) 2)))
(cond ((> (vector-ref vector middle) value)
(helper low (- middle 1)))
((< (vector-ref vector middle) value)
(helper (+ middle 1) high))
(else middle))))))

View file

@ -0,0 +1,25 @@
proc binSrch {lst x} {
set len [llength $lst]
if {$len == 0} {
return -1
} else {
set pivotIndex [expr {$len / 2}]
set pivotValue [lindex $lst $pivotIndex]
if {$pivotValue == $x} {
return $pivotIndex
} elseif {$pivotValue < $x} {
set recursive [binSrch [lrange $lst $pivotIndex+1 end] $x]
return [expr {$recursive > -1 ? $recursive + $pivotIndex + 1 : -1}]
} elseif {$pivotValue > $x} {
set recursive [binSrch [lrange $lst 0 $pivotIndex-1] $x]
return [expr {$recursive > -1 ? $recursive : -1}]
}
}
}
proc binary_search {lst x} {
if {[set idx [binSrch $lst $x]] == -1} {
puts "element $x not found in list"
} else {
puts "element $x found at index $idx"
}
}

View file

@ -0,0 +1,8 @@
proc binarySearch {lst x} {
set idx [lsearch -sorted -exact $lst $x]
if {$idx == -1} {
puts "element $x not found in list"
} else {
puts "element $x found at index $idx"
}
}