change API of BinVec
This commit is contained in:
@@ -1,37 +1,32 @@
|
|||||||
signature BIN_VEC =
|
signature MAKE_BIN_VEC =
|
||||||
sig
|
sig
|
||||||
(* char is just 8 bits, which is smaller than int's 32 bits
|
type elem
|
||||||
* and smaller = faster here*)
|
|
||||||
type elem = char
|
|
||||||
type t = char vector
|
|
||||||
|
|
||||||
val singleton: elem -> t
|
val l: elem * elem -> bool
|
||||||
val getIndex: t * elem -> int
|
val eq: elem * elem -> bool
|
||||||
val insert: t * elem -> t
|
val g: elem * elem -> bool
|
||||||
end
|
end
|
||||||
|
|
||||||
structure BinVec: BIN_VEC =
|
signature BIN_VEC =
|
||||||
|
sig
|
||||||
|
type elem
|
||||||
|
|
||||||
|
val empty: elem vector
|
||||||
|
|
||||||
|
val sub: elem vector * int -> elem
|
||||||
|
|
||||||
|
val findInsPos: elem * elem vector -> int
|
||||||
|
val insert: elem vector * elem * int -> elem vector
|
||||||
|
val delete: elem vector * elem -> elem vector
|
||||||
|
end
|
||||||
|
|
||||||
|
functor MakeBinVec(Fn: MAKE_BIN_VEC): BIN_VEC =
|
||||||
struct
|
struct
|
||||||
type elem = char
|
type elem = Fn.elem
|
||||||
type t = char vector
|
|
||||||
|
|
||||||
fun singleton x = Vector.fromList [x]
|
val empty = Vector.fromList []
|
||||||
|
|
||||||
fun helpFind (findNum, vec, low, high) =
|
val sub = Vector.sub
|
||||||
if high >= low then
|
|
||||||
let
|
|
||||||
val mid = low + ((high - low) div 2)
|
|
||||||
val curNum = Vector.sub (vec, mid)
|
|
||||||
in
|
|
||||||
if curNum = findNum then mid
|
|
||||||
else if curNum < findNum then helpFind (findNum, vec, mid + 1, high)
|
|
||||||
else helpFind (findNum, vec, low, mid - 1)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
~1
|
|
||||||
|
|
||||||
fun getIndex (vec: t, findNum: elem) =
|
|
||||||
helpFind (findNum, vec, 0, Vector.length vec - 1)
|
|
||||||
|
|
||||||
fun reverseLinearSearch (pos, findNum, vec) =
|
fun reverseLinearSearch (pos, findNum, vec) =
|
||||||
if pos < 0 then
|
if pos < 0 then
|
||||||
@@ -40,7 +35,7 @@ struct
|
|||||||
let
|
let
|
||||||
val curNum = Vector.sub (vec, pos)
|
val curNum = Vector.sub (vec, pos)
|
||||||
in
|
in
|
||||||
if findNum > curNum then pos + 1
|
if Fn.g (findNum, curNum) then pos + 1
|
||||||
else reverseLinearSearch (pos - 1, findNum, vec)
|
else reverseLinearSearch (pos - 1, findNum, vec)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -51,7 +46,7 @@ struct
|
|||||||
let
|
let
|
||||||
val curNum = Vector.sub (vec, pos)
|
val curNum = Vector.sub (vec, pos)
|
||||||
in
|
in
|
||||||
if findNum > curNum then pos
|
if Fn.g (findNum, curNum) then pos
|
||||||
else forwardLinearSearch (pos + 1, findNum, vec)
|
else forwardLinearSearch (pos + 1, findNum, vec)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -61,9 +56,9 @@ struct
|
|||||||
val mid = low + ((high - low) div 2)
|
val mid = low + ((high - low) div 2)
|
||||||
val curNum = Vector.sub (vec, mid)
|
val curNum = Vector.sub (vec, mid)
|
||||||
in
|
in
|
||||||
if curNum = findNum then
|
if Fn.eq (curNum, findNum) then
|
||||||
mid
|
mid
|
||||||
else if curNum < findNum then
|
else if Fn.l (curNum, findNum) then
|
||||||
helpFindInsPos (findNum, vec, mid + 1, high, mid)
|
helpFindInsPos (findNum, vec, mid + 1, high, mid)
|
||||||
else
|
else
|
||||||
helpFindInsPos (findNum, vec, low, mid - 1, mid)
|
helpFindInsPos (findNum, vec, low, mid - 1, mid)
|
||||||
@@ -72,18 +67,22 @@ struct
|
|||||||
let
|
let
|
||||||
val curNum = Vector.sub (vec, prevMid)
|
val curNum = Vector.sub (vec, prevMid)
|
||||||
in
|
in
|
||||||
if findNum < curNum then forwardLinearSearch (prevMid, findNum, vec)
|
if Fn.l (findNum, curNum) then
|
||||||
else reverseLinearSearch (prevMid, findNum, vec)
|
forwardLinearSearch (prevMid, findNum, vec)
|
||||||
|
else
|
||||||
|
reverseLinearSearch (prevMid, findNum, vec)
|
||||||
end
|
end
|
||||||
|
|
||||||
fun findInsPos (findNum, vec) =
|
fun findInsPos (findNum, vec) =
|
||||||
if Vector.length vec = 0 then ~1
|
if Vector.length vec = 0 then ~1
|
||||||
else helpFindInsPos (findNum, vec, 0, Vector.length vec - 1, 0)
|
else helpFindInsPos (findNum, vec, 0, Vector.length vec - 1, 0)
|
||||||
|
|
||||||
fun insert (vec: t, elem: elem) =
|
(* insPos parameter should be the unmodified result of calling findInsPos.
|
||||||
let
|
* The reason the insert function does not call findInsPos directly is so,
|
||||||
val insPos = findInsPos (elem, vec)
|
* if two BinVecs are used (one for keys and another for values like a map)
|
||||||
in
|
* then the insert function can be used for both the key vector and value
|
||||||
|
* vector *)
|
||||||
|
fun insert (vec, elem, insPos) =
|
||||||
if insPos < 0 then
|
if insPos < 0 then
|
||||||
Vector.concat [Vector.fromList [elem], vec]
|
Vector.concat [Vector.fromList [elem], vec]
|
||||||
else if insPos = Vector.length vec then
|
else if insPos = Vector.length vec then
|
||||||
@@ -99,9 +98,8 @@ struct
|
|||||||
in
|
in
|
||||||
VectorSlice.concat [slice1, elem, slice2]
|
VectorSlice.concat [slice1, elem, slice2]
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
fun delete (vec, elem) =
|
fun delete (vec, elem: elem) =
|
||||||
let
|
let
|
||||||
val insPos = findInsPos (elem, vec)
|
val insPos = findInsPos (elem, vec)
|
||||||
in
|
in
|
||||||
@@ -118,3 +116,13 @@ struct
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
structure IntBinVec =
|
||||||
|
MakeBinVec
|
||||||
|
(struct
|
||||||
|
type elem = int
|
||||||
|
|
||||||
|
val l = Int.<
|
||||||
|
fun eq (a, b) = a = b
|
||||||
|
val g = Int.>
|
||||||
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user