seem to have fixed error with 'exists' function previously mentioned in todo, without introducing regressions
This commit is contained in:
@@ -79,64 +79,62 @@ struct
|
|||||||
fun helpExists (searchKey, keyPos, trie) =
|
fun helpExists (searchKey, keyPos, trie) =
|
||||||
case trie of
|
case trie of
|
||||||
CHILDREN {keys, children} =>
|
CHILDREN {keys, children} =>
|
||||||
if keyPos = String.size searchKey then
|
let
|
||||||
false
|
val findChr = String.sub (searchKey, keyPos)
|
||||||
else
|
in
|
||||||
let
|
(case findBinSearch (findChr, keyPos, keys) of
|
||||||
val findChr = String.sub (searchKey, keyPos)
|
SOME idx =>
|
||||||
in
|
let
|
||||||
(case findBinSearch (findChr, keyPos, keys) of
|
val trieKey = Vector.sub (keys, idx)
|
||||||
SOME idx =>
|
in
|
||||||
let
|
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
||||||
val trieKey = Vector.sub (keys, idx)
|
NO_SEARCH_MATCH => false
|
||||||
in
|
| FULL_SEARCH_MATCH =>
|
||||||
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
let val trieChild = Vector.sub (children, idx)
|
||||||
NO_SEARCH_MATCH => false
|
in isFoundNode trieChild
|
||||||
| FULL_SEARCH_MATCH =>
|
end
|
||||||
let val trieChild = Vector.sub (children, idx)
|
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
||||||
in isFoundNode trieChild
|
let val trieChild = Vector.sub (children, idx)
|
||||||
end
|
in helpExists (searchKey, String.size trieKey, trieChild)
|
||||||
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
end
|
||||||
let
|
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
||||||
val trieChild = Vector.sub (children, idx)
|
end
|
||||||
in
|
| NONE => false)
|
||||||
helpExists
|
end
|
||||||
(searchKey, keyPos + String.size trieKey, trieChild)
|
|
||||||
end
|
|
||||||
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
|
||||||
end
|
|
||||||
| NONE => false)
|
|
||||||
end
|
|
||||||
| FOUND_WITH_CHILDREN {keys, children} =>
|
| FOUND_WITH_CHILDREN {keys, children} =>
|
||||||
if keyPos = String.size searchKey then
|
let
|
||||||
true
|
val findChr = String.sub (searchKey, keyPos)
|
||||||
else
|
in
|
||||||
let
|
(case findBinSearch (findChr, keyPos, keys) of
|
||||||
val findChr = String.sub (searchKey, keyPos)
|
SOME idx =>
|
||||||
in
|
let
|
||||||
(case findBinSearch (findChr, keyPos, keys) of
|
val trieKey = Vector.sub (keys, idx)
|
||||||
SOME idx =>
|
in
|
||||||
let
|
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
||||||
val trieKey = Vector.sub (keys, idx)
|
NO_SEARCH_MATCH => false
|
||||||
in
|
| FULL_SEARCH_MATCH =>
|
||||||
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
let val trieChild = Vector.sub (children, idx)
|
||||||
NO_SEARCH_MATCH => false
|
in isFoundNode trieChild
|
||||||
| FULL_SEARCH_MATCH =>
|
end
|
||||||
let val trieChild = Vector.sub (children, idx)
|
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
||||||
in isFoundNode trieChild
|
let val trieChild = Vector.sub (children, idx)
|
||||||
end
|
in helpExists (searchKey, String.size trieKey, trieChild)
|
||||||
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
end
|
||||||
let
|
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
||||||
val trieChild = Vector.sub (children, idx)
|
end
|
||||||
in
|
| NONE => false)
|
||||||
helpExists
|
end
|
||||||
(searchKey, keyPos + String.size trieKey, trieChild)
|
| FOUND =>
|
||||||
end
|
(*
|
||||||
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
* This case should only occur if we recurse in a node
|
||||||
end
|
* when there is a partial, but not full, string match.
|
||||||
| NONE => false)
|
* This is because of the isFoundNode helper function
|
||||||
end
|
* which is called by the parent.
|
||||||
| FOUND => keyPos = String.size searchKey - 1
|
* In other words, only the parent node returns true,
|
||||||
|
* by checking if the child is a found node and has
|
||||||
|
* a full string match.
|
||||||
|
*)
|
||||||
|
false
|
||||||
|
|
||||||
fun exists (searchKey, trie) = helpExists (searchKey, 0, trie)
|
fun exists (searchKey, trie) = helpExists (searchKey, 0, trie)
|
||||||
|
|
||||||
@@ -155,8 +153,7 @@ struct
|
|||||||
let
|
let
|
||||||
val trieChild = Vector.sub (children, idx)
|
val trieChild = Vector.sub (children, idx)
|
||||||
in
|
in
|
||||||
helpGetPrefixSubtrie
|
helpGetPrefixSubtrie (prefix, String.size trieKey, trieChild)
|
||||||
(prefix, keyPos + String.size trieKey, trieChild)
|
|
||||||
end
|
end
|
||||||
| FULL_SEARCH_MATCH =>
|
| FULL_SEARCH_MATCH =>
|
||||||
let val node = Vector.sub (children, idx)
|
let val node = Vector.sub (children, idx)
|
||||||
@@ -177,7 +174,7 @@ struct
|
|||||||
| FOUND_WITH_CHILDREN {keys, children} =>
|
| FOUND_WITH_CHILDREN {keys, children} =>
|
||||||
helpGetPrefixSubtrieChildren (prefix, keyPos, keys, children, trie)
|
helpGetPrefixSubtrieChildren (prefix, keyPos, keys, children, trie)
|
||||||
| FOUND =>
|
| FOUND =>
|
||||||
if keyPos = String.size prefix then
|
if keyPos = String.size prefix - 1 then
|
||||||
let val node = fromString prefix
|
let val node = fromString prefix
|
||||||
in SOME node
|
in SOME node
|
||||||
end
|
end
|
||||||
@@ -209,7 +206,7 @@ struct
|
|||||||
|
|
||||||
fun getPrefixList (prefix, trie) =
|
fun getPrefixList (prefix, trie) =
|
||||||
case getPrefixSubtrie (prefix, trie) of
|
case getPrefixSubtrie (prefix, trie) of
|
||||||
SOME subtrie => helpGetPrefixList (trie, [])
|
SOME subtrie => helpGetPrefixList (subtrie, [])
|
||||||
| NONE => []
|
| NONE => []
|
||||||
|
|
||||||
datatype insert_string_match =
|
datatype insert_string_match =
|
||||||
@@ -351,9 +348,8 @@ struct
|
|||||||
fun foundInsertPos (keys, children, keyPos, insKey, insIdx, trie, constructor) =
|
fun foundInsertPos (keys, children, keyPos, insKey, insIdx, trie, constructor) =
|
||||||
let
|
let
|
||||||
val trieKey = Vector.sub (keys, insIdx)
|
val trieKey = Vector.sub (keys, insIdx)
|
||||||
val nextKeyPos = keyPos + 1
|
|
||||||
in
|
in
|
||||||
(case insertKeyMatch (insKey, trieKey, nextKeyPos) of
|
(case insertKeyMatch (insKey, trieKey, keyPos + 1) of
|
||||||
(* may need to split string if difference found but prefix matched *)
|
(* may need to split string if difference found but prefix matched *)
|
||||||
DIFFERENCE_FOUND_AT diffIdx =>
|
DIFFERENCE_FOUND_AT diffIdx =>
|
||||||
let
|
let
|
||||||
@@ -410,8 +406,8 @@ struct
|
|||||||
| INSERT_KEY_CONTAINS_TRIE_KEY =>
|
| INSERT_KEY_CONTAINS_TRIE_KEY =>
|
||||||
let
|
let
|
||||||
val trieChild = Vector.sub (children, insIdx)
|
val trieChild = Vector.sub (children, insIdx)
|
||||||
val newTrieChild = helpInsert
|
val newTrieChild =
|
||||||
(insKey, keyPos + String.size trieKey, trieChild)
|
helpInsert (insKey, String.size trieKey, trieChild)
|
||||||
val newChildren =
|
val newChildren =
|
||||||
Vector.mapi
|
Vector.mapi
|
||||||
(fn (idx, elt) => if idx <> insIdx then elt else newTrieChild)
|
(fn (idx, elt) => if idx <> insIdx then elt else newTrieChild)
|
||||||
@@ -508,4 +504,10 @@ struct
|
|||||||
* todo:
|
* todo:
|
||||||
* - Test prefix searching, which turns found strings to list.
|
* - Test prefix searching, which turns found strings to list.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
val trie = fromList ["hello", "hit", "hi", "henlo", "help"]
|
||||||
|
val lst = getPrefixList ("hi", trie)
|
||||||
|
val helloExists = exists ("hello", trie)
|
||||||
|
val hitExists = exists ("hit", trie)
|
||||||
|
val hiExists = exists ("hi", trie)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user