我需要尝试计算具有固定功能的彩票中奖金额。对于功能,我需要知道每个节点有多少个子代。首先,我需要创建特里树,然后对其进行搜索以找出赢得了多少张彩票。 请注意,我是SML的新手,因此我确实没有太多经验。 我在其他要修改的帖子中找到了类似的代码(下面的链接)。 Inserting values in a Trie
此代码的问题在于,当我通过Trie时,我无法更改节点的权重。例如:如果我已经插入了数字1234(从左到右开始),则每个节点的权重为1。如果我想添加数字1255,我想修改节点1和2的权重。等于2(基本上是+1)。
PS我的练习有很多时间限制,因此我试图尽可能高效,快速地做到这一点。
我尝试用我想将其权重增加1的节点再次调用insert函数,但是我得到一个引用数据类型的错误。 我试图更改节点的数据类型,但出现更多错误
signature DICT = sig
type key = string (* concrete type *)
type 'a entry = key * 'a (* concrete type *)
type 'a dict (* abstract type *)
val empty : 'a dict
val lookup : 'a dict -> key -> 'a option
val insert : 'a dict * 'a entry -> 'a dict
val toString : ('a -> string) -> 'a dict -> string
end; (* signature DICT *)
exception InvariantViolationException
structure Trie :> DICT =
struct
type key = string
type 'a entry = key * 'a
datatype 'a trie =
Root of 'a option * 'a trie list
| Node of 'a option * char * 'a trie list
type 'a dict = 'a trie
val empty = Root(NONE, nil)
(* val lookup: 'a dict -> key -> 'a option *)
fun lookup trie key =
let
(* val lookupList: 'a trie list * char list -> 'a option *)
fun lookupList (nil, _) = NONE
| lookupList (_, nil) = raise InvariantViolationException
| lookupList ((trie as Node(_, letter', _))::lst, key as letter::rest) =
if letter = letter' then lookup' (trie, rest)
else lookupList (lst, key)
| lookupList (_, _) =
raise InvariantViolationException
(*
val lookup': 'a trie -> char list
*)
and lookup' (Root(elem, _), nil) = elem
| lookup' (Root(_, lst), key) = lookupList (lst, key)
| lookup' (Node(elem, _, _), nil) = elem
| lookup' (Node(elem, letter, lst), key) = lookupList (lst, key)
in
lookup' (trie, explode key)
end
(*
val insert: 'a dict * 'a entry -> 'a dict
*)
fun insert (trie, (key, value)) =
let
(*
val insertChild: 'a trie list * key * value -> 'a trie list
Searches a list of tries to insert the value. If a matching letter
prefix is found, it peels of a letter from the key and calls insert'.
If no matching letter prefix is found, a new trie is added to the list.
Invariants:
* key is never nil.
* The trie list does not contain a Root.
Effects: none
*)
fun insertChild (nil, letter::nil, value) =[ Node(SOME(value), letter, nil) ]
| insertChild (nil, letter::rest, value) = [ Node(SOME(value), letter, insertChild (nil, rest, value)) ]
| insertChild ((trie as Node(SOME(oldvalue), letter', _))::lst, key as letter::rest, value) =
if letter = letter' then
let
val newvalue = oldvalue+1
val ltrie=insertChild(trie::lst,letter'::nil, newvalue)
val trie = hd ltrie
in
insert' (trie, rest, value) :: lst
end
else
trie :: insertChild (lst, key, value)
| insertChild (Root(_,_)::lst, letter::rest, value) = raise InvariantViolationException
| insertChild (_, nil, _) = (* invariant: key is never nil *)raise InvariantViolationException
(*val insert': 'a trie * char list * 'a -> 'a trie
Invariants:* The value is on the current branch, including potentially the current node we're on.* If the key is nil, assumes the current node is the destination.Effects: none*)
and insert' (Root(_, lst), nil, value) = Root(SOME(value), lst)
| insert' (Root(elem, lst), key, value)=Root(elem,insertChild(lst,key, value))
| insert' (Node(_, letter, lst), nil, value)=Node(SOME(value),letter,lst)
| insert' (Node(elem, letter, lst), key, value)=Node(elem,letter,insertChild (lst, key, value))
in
insert'(trie, explode key, value)
end
我得到的错误在于以下几行:
val newvalue = oldvalue+1
val ltrie = insertChild (trie::lst, letter'::nil, newvalue)
结果:
Error:
lott.sml:72.10-72.31 Error: operator and operand do not agree [overload conflict]
operator domain: [+ ty] * [+ ty]
operand: 'Z option * [int ty]
in expression:
oldvalue + 1