class BinarySearch
{
private $start = null;
private $end = null;
private $calculatedLength = null;
private $elements = array();
private $searchingEliment = null;
/**
* @param $searchEliment
* @param array $eliments
* @return int
*/
public function search($searchEliment, array $eliments = array())
{
$this->searchingEliment = (int) $searchEliment;
$this->elements = $eliments;
$totalElement = count($this->elements);
$currentElement = current($this->elements);
$this->start = 0;
$this->end = $totalElement - 1;
if (($totalElement == 0) || ($totalElement == 1
&& $currentElement != $this->searchingEliment))
return -1;
if ($totalElement == 1 && $currentElement == $this->searchingEliment)
return $this->start;
while (true) {
$this->calculatedLength = $this->start + $this->end;
if ($this->calculatedLength == 1) {
if ($this->elements[$this->start] == $this->searchingEliment) {
return $this->start;
} else if ($this->elements[$this->end] == $this->searchingEliment) {
return $this->end;
} else {
return -1;
}
}
$mid = ceil($this->calculatedLength / 2);
if ($this->elements[$mid] == $this->searchingEliment)
return $mid;
if ($this->end == $mid)
return -1;
if ($this->elements[$mid] < $this->searchingEliment)
$this->start = $mid;
if ($this->elements[$mid] > $this->searchingEliment)
$this->end = $mid;
}
}
}
class BinarySearchTest extends PHPUnit_Framework_TestCase
{
public function testBinarySearchReturnIndex()
{
$binarySearch = new RequiresiveBinarySearch();
$this->assertEquals($binarySearch->search(2, array(1, 2)), 1);
$this->assertEquals($binarySearch->search(3, array()), -1);
$this->assertEquals($binarySearch->search(3, array()), -1);
$this->assertEquals(-1, $binarySearch->search(3, [1]));
$this->assertEquals(0, $binarySearch->search(1, [1]));
$this->assertEquals(0, $binarySearch->search(1, [1, 3, 5]));
$this->assertEquals(1, $binarySearch->search(3, [1, 3, 5]));
$this->assertEquals(2, $binarySearch->search(5, [1, 3, 5]));
$this->assertEquals(-1, $binarySearch->search(0, [1, 3, 5]));
$this->assertEquals(-1, $binarySearch->search(2, [1, 3, 5]));
$this->assertEquals(-1, $binarySearch->search(4, [1, 3, 5]));
$this->assertEquals(-1, $binarySearch->search(6, [1, 3, 5]));
$this->assertEquals(0, $binarySearch->search(1, [1, 3, 5, 7]));
$this->assertEquals(1, $binarySearch->search(3, [1, 3, 5, 7]));
$this->assertEquals(2, $binarySearch->search(5, [1, 3, 5, 7]));
$this->assertEquals(3, $binarySearch->search(7, [1, 3, 5, 7]));
$this->assertEquals(-1, $binarySearch->search(0, [1, 3, 5, 7]));
$this->assertEquals(-1, $binarySearch->search(2, [1, 3, 5, 7]));
$this->assertEquals(-1, $binarySearch->search(4, [1, 3, 5, 7]));
$this->assertEquals(-1, $binarySearch->search(6, [1, 3, 5, 7]));
$this->assertEquals(4, $binarySearch->search(67, [1, 3, 5, 7, 67]));
$this->assertEquals(-1, $binarySearch->search(8, [1, 3, 5, 7]));
}
}