fixed 'helpExists' function; error was in the FOUND case which checked 'keyPos = String.size searchKey' instead of 'keyPos = String.size searchKey - 1'. The latter is correct, because it checks that the keyPos ended at the last character, which is the intended meaning
This commit is contained in:
@@ -79,58 +79,64 @@ struct
|
|||||||
fun helpExists (searchKey, keyPos, trie) =
|
fun helpExists (searchKey, keyPos, trie) =
|
||||||
case trie of
|
case trie of
|
||||||
CHILDREN {keys, children} =>
|
CHILDREN {keys, children} =>
|
||||||
let
|
if keyPos = String.size searchKey then
|
||||||
val findChr = String.sub (searchKey, keyPos)
|
false
|
||||||
in
|
else
|
||||||
(case findBinSearch (findChr, keyPos, keys) of
|
let
|
||||||
SOME idx =>
|
val findChr = String.sub (searchKey, keyPos)
|
||||||
let
|
in
|
||||||
val trieKey = Vector.sub (keys, idx)
|
(case findBinSearch (findChr, keyPos, keys) of
|
||||||
in
|
SOME idx =>
|
||||||
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
let
|
||||||
NO_SEARCH_MATCH => false
|
val trieKey = Vector.sub (keys, idx)
|
||||||
| FULL_SEARCH_MATCH =>
|
in
|
||||||
let val trieChild = Vector.sub (children, idx)
|
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
||||||
in isFoundNode trieChild
|
NO_SEARCH_MATCH => false
|
||||||
end
|
| FULL_SEARCH_MATCH =>
|
||||||
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
let val trieChild = Vector.sub (children, idx)
|
||||||
let
|
in isFoundNode trieChild
|
||||||
val trieChild = Vector.sub (children, idx)
|
end
|
||||||
in
|
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
||||||
helpExists
|
let
|
||||||
(searchKey, keyPos + String.size trieKey, trieChild)
|
val trieChild = Vector.sub (children, idx)
|
||||||
end
|
in
|
||||||
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
helpExists
|
||||||
end
|
(searchKey, keyPos + String.size trieKey, trieChild)
|
||||||
| NONE => false)
|
end
|
||||||
end
|
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
||||||
|
end
|
||||||
|
| NONE => false)
|
||||||
|
end
|
||||||
| FOUND_WITH_CHILDREN {keys, children} =>
|
| FOUND_WITH_CHILDREN {keys, children} =>
|
||||||
let
|
if keyPos = String.size searchKey then
|
||||||
val findChr = String.sub (searchKey, keyPos)
|
true
|
||||||
in
|
else
|
||||||
(case findBinSearch (findChr, keyPos, keys) of
|
let
|
||||||
SOME idx =>
|
val findChr = String.sub (searchKey, keyPos)
|
||||||
let
|
in
|
||||||
val trieKey = Vector.sub (keys, idx)
|
(case findBinSearch (findChr, keyPos, keys) of
|
||||||
in
|
SOME idx =>
|
||||||
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
let
|
||||||
NO_SEARCH_MATCH => false
|
val trieKey = Vector.sub (keys, idx)
|
||||||
| FULL_SEARCH_MATCH =>
|
in
|
||||||
let val trieChild = Vector.sub (children, idx)
|
(case searchKeyMatch (searchKey, trieKey, keyPos + 1) of
|
||||||
in isFoundNode trieChild
|
NO_SEARCH_MATCH => false
|
||||||
end
|
| FULL_SEARCH_MATCH =>
|
||||||
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
let val trieChild = Vector.sub (children, idx)
|
||||||
let
|
in isFoundNode trieChild
|
||||||
val trieChild = Vector.sub (children, idx)
|
end
|
||||||
in
|
| SEARCH_KEY_CONTAINS_TRIE_KEY =>
|
||||||
helpExists
|
let
|
||||||
(searchKey, keyPos + String.size trieKey, trieChild)
|
val trieChild = Vector.sub (children, idx)
|
||||||
end
|
in
|
||||||
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
helpExists
|
||||||
end
|
(searchKey, keyPos + String.size trieKey, trieChild)
|
||||||
| NONE => false)
|
end
|
||||||
end
|
| TRIE_KEY_CONTAINS_SEARCH_KEY => false)
|
||||||
| FOUND => keyPos = String.size searchKey
|
end
|
||||||
|
| NONE => false)
|
||||||
|
end
|
||||||
|
| FOUND => keyPos = String.size searchKey - 1
|
||||||
|
|
||||||
fun exists (searchKey, trie) = helpExists (searchKey, 0, trie)
|
fun exists (searchKey, trie) = helpExists (searchKey, 0, trie)
|
||||||
|
|
||||||
@@ -402,8 +408,16 @@ struct
|
|||||||
FOUND_WITH_CHILDREN {keys = keys, children = children}
|
FOUND_WITH_CHILDREN {keys = keys, children = children}
|
||||||
(* if insert key contains trie key, need to recurse down node *)
|
(* if insert key contains trie key, need to recurse down node *)
|
||||||
| INSERT_KEY_CONTAINS_TRIE_KEY =>
|
| INSERT_KEY_CONTAINS_TRIE_KEY =>
|
||||||
let val trieChild = Vector.sub (children, insIdx)
|
let
|
||||||
in helpInsert (insKey, keyPos + String.size trieKey, trieChild)
|
val trieChild = Vector.sub (children, insIdx)
|
||||||
|
val newTrieChild = helpInsert
|
||||||
|
(insKey, keyPos + String.size trieKey, trieChild)
|
||||||
|
val newChildren =
|
||||||
|
Vector.mapi
|
||||||
|
(fn (idx, elt) => if idx <> insIdx then elt else newTrieChild)
|
||||||
|
children
|
||||||
|
in
|
||||||
|
constructor {keys = keys, children = newChildren}
|
||||||
end
|
end
|
||||||
(* if trie key contains insert key, need to split node *)
|
(* if trie key contains insert key, need to split node *)
|
||||||
| TRIE_KEY_CONTAINS_INSERT_KEY =>
|
| TRIE_KEY_CONTAINS_INSERT_KEY =>
|
||||||
@@ -411,7 +425,7 @@ struct
|
|||||||
val trieChild = Vector.sub (children, insIdx)
|
val trieChild = Vector.sub (children, insIdx)
|
||||||
val newKeys =
|
val newKeys =
|
||||||
Vector.mapi
|
Vector.mapi
|
||||||
(fn (idx, key) => if idx <> insIdx then insKey else key) keys
|
(fn (idx, key) => if idx <> insIdx then key else insKey) keys
|
||||||
|
|
||||||
(* newTrieChild should always be FOUND_WITH_CHILDREN,
|
(* newTrieChild should always be FOUND_WITH_CHILDREN,
|
||||||
* because previous part matches insert key,
|
* because previous part matches insert key,
|
||||||
@@ -492,13 +506,16 @@ struct
|
|||||||
|
|
||||||
(*
|
(*
|
||||||
* todo:
|
* todo:
|
||||||
* - Fix insert function.
|
* - Fix exists function
|
||||||
* - Once insert is fixed, test prefix searching,
|
* - Test prefix searching, which turns found strings to list.
|
||||||
* which turns found strings to list.
|
|
||||||
*
|
*
|
||||||
* Problem with insert function:
|
* Problem with exists function:
|
||||||
* The "trie" value below does not contain "hello". It somehow disappeared.
|
* exists ("hello", trie) returns true as expected
|
||||||
* Should probably attempt to create a test suite, to catch regressions as well.
|
* but exists ("hellop", trie) also returns true
|
||||||
|
* even though "hellop" was never added.
|
||||||
|
*
|
||||||
|
* "helloz" also returns true, although "hellopo" returns false.
|
||||||
|
* Problem occurs when trieKey length > searchKey length + 1 apparently.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
val trie = fromList ["hello", "hit", "hi"]
|
val trie = fromList ["hello", "hit", "hi"]
|
||||||
|
|||||||
Reference in New Issue
Block a user