我想将字符串列表转换为三元树。树应具有以下数据类型
datatype ttree = node of string*ttree list*string|leaf of string*string*string
例如,
["<root>","<a3>","<b2>","Father","</b2>","<b3>","Mother","</b3>","</a3>","<a1>","<ffx>","AAA",...] : string list
应转换为
val test =
node
("<root>",
[node
("<a3>",
[leaf ("<b2>","Father","<b2>"),leaf ("<b3>","Mother","<b3>")],
"<a3>"),
node
("<a1>",[leaf ("<ffx>","AAA","<ffx>"),leaf ("<ff>","BBB","<ff>")],
"<a1>")],"<root>") : ttree
答案 0 :(得分:3)
不是最有效的解决方案,但这应该可以解决问题:
datatype ttree = node of string*ttree list*string | leaf of string*string*string
val l = ["<root>",
"<a3>",
"<b2>","Father","</b2>",
"<b3>","Mother","</b3>",
"</a3>",
"<a1>",
"<ffx>","AAA","</ffx>",
"</a1>"]
(*listToTree(l) = string list to ternary tree*)
fun listToTree(l : string list) : ttree =
let
(*isLeaf(s1, s3) = true if s1=<a> and s3=</a>,
a can be replaced with anything
false otherwise*)
fun isLeaf(s1 : string, s3 : string) : bool =
let
val (e1, e3) = (explode s1, explode s3)
val (t1c1::t1) = e1
val t1e = List.last t1
val (t3c1::t3c2::t3) = e3
val t3e = List.last t3
in
if t1c1 = #"<" andalso
t1c1 = t3c1 andalso
t1e = #">" andalso
t1e = t3e andalso
t3c2 = #"/" andalso
t1 = t3 then true else false
end
(*parseUntil(l, until, acc) = (p, r),
where p = acc + a part of l until an element x
that satisfies isLeaf(until,x)
and r = elements of list l after x *)
fun parseUntil(l : string list, until : string, acc : string list)
: string list * string list =
case l of
[] => (rev acc, [])
| x::xs => if isLeaf(until, x)
then (rev acc, xs)
else parseUntil(xs, until, x::acc)
(*parseList(l) = the ttree list of the given string list*)
fun parseList(l : string list) : ttree list =
case l of
[] => []
| x::xs => let
val (parsed, rest) = parseUntil(xs, x, [])
in
if length parsed = 1
then leaf(x, hd xs, x)::parseList(rest)
else node(x, parseList(parsed), x)::parseList(rest)
end
in
hd (parseList l)
end
val result = listToTree l;
它基本上是这样做的:
获得标记后,获取列表元素,直到关闭标记。
使用元素调用相同的解析器函数,直到close标记,并将结果放在节点的列表中。
使用close标记后面的元素调用相同的解析器函数,并将它们附加到上一级列表。
我希望我能提供帮助。