Merge pull request #1032 from barcharcraz/lowerBound

Added lowerBound function to the stdlib
This commit is contained in:
Varriount
2014-03-27 15:08:19 -04:00
2 changed files with 32 additions and 0 deletions

View File

@@ -55,6 +55,35 @@ proc smartBinarySearch*[T](a: openArray[T], key: T): int =
const
onlySafeCode = true
proc lowerBound*[T](a: openarray[T], key: T, cmp: proc(x,y: T): int {.closure.}): int =
## same as binarySearch except that if key is not in `a` then this
## returns the location where `key` would be if it were. In other
## words if you have a sorted sequence and you call insert(thing, elm, lowerBound(thing, elm))
## the sequence will still be sorted
##
## `cmp` is the comparator function to use, the expected return values are the same as
## that of system.cmp
##
## example:
## `var arr = @[1,2,3,5,6,7,8,9]`
## `arr.insert(4, arr.lowerBound(4))`
## after running the above arr is `[1,2,3,4,5,6,7,8,9]`
result = a.low
var pos = result
var count, step: int
count = a.high - a.low + 1
while count != 0:
pos = result
step = count div 2
pos += step
if cmp(a[pos], key) < 0:
pos.inc
result = pos
count -= step + 1
else:
count = step
proc lowerBound*[T](a: openarray[T], key: T): int = lowerBound(a, key, cmp[T])
proc merge[T](a, b: var openArray[T], lo, m, hi: int,
cmp: proc (x, y: T): int {.closure.}, order: TSortOrder) =
template `<-` (a, b: expr) =

View File

@@ -6,3 +6,6 @@ doAssert product(@[@[1,2]]) == @[@[1,2]], "a simple case of one element"
doAssert product(@[@[1,2], @[3,4]]) == @[@[2,4],@[1,4],@[2,3],@[1,3]], "two elements"
doAssert product(@[@[1,2], @[3,4], @[5,6]]) == @[@[2,4,6],@[1,4,6],@[2,3,6],@[1,3,6], @[2,4,5],@[1,4,5],@[2,3,5],@[1,3,5]], "three elements"
doAssert product(@[@[1,2], @[]]) == newSeq[seq[int]](), "two elements, but one empty"
doAssert lowerBound([1,2,4], 3, system.cmp[int]) == 2
doAssert lowerBound([1,2,2,3], 4, system.cmp[int]) == 4
doAssert lowerBound([1,2,3,10], 11) == 4