【发布时间】:2020-02-10 19:25:09
【问题描述】:
我正在学习 OCaml,现在卡在了代码上。 这是一个从图表中创建可访问节点列表的代码。
type graph = (vertex * vertex) list
and vertex = int
let rec sort lst =
match lst with
[] -> []
| h::t -> insert h (sort t)
and insert n lst =
match lst with
[] -> [n]
| h::t -> if n <= h then n :: lst else h :: insert n t;;
let rec remove lst =
match lst with
| [] -> []
| x::[] -> x::[]
| x::y::tl ->
if x=y then remove (y::tl)
else x::remove (y::tl);;
let rec reach : graph * vertex -> vertex list
= fun (g, v) ->
match g with
|[] -> []
|h::t ->let x = [] in
match h with
|a,b -> if a = v then remove(sort(v::x) @ (reach (g, b)))
else
remove(sort(v::reach (t, v)));;
reach([(1,2);(2,3);(3,4);(4,2);(2,5)],4);;
我认为由于我缺乏编码能力,我的代码变得毫无意义地复杂。 此外,我现在面临的主要问题是我无法使递归函数“到达”以访问原始列表“g”,因为它在使用列表“t”访问时在 else 条件下递归。
痕迹说
reach <-- ([(1, 2); (2, 3); (3, 4); (4, 2); (2, 5)], 4)
reach <-- ([(2, 3); (3, 4); (4, 2); (2, 5)], 4)
reach <-- ([(3, 4); (4, 2); (2, 5)], 4)
reach <-- ([(4, 2); (2, 5)], 4)
reach <-- ([(4, 2); (2, 5)], 2)
reach <-- ([(2, 5)], 2)
reach <-- ([(2, 5)], 5)
reach <-- ([], 5)
reach --> []
reach --> [5]
reach --> [2; 5]
reach --> [2; 5]
reach --> [4; 2; 5]
reach --> [2; 4; 5]
reach --> [2; 4; 5]
reach --> [2; 4; 5]
- : vertex list = [2; 4; 5]
首先,我使用 let y = g 声明了一个新变量并更改了代码
|a,b -> if a = v then remove(sort(v::x) @ (reach (y, b)))
else
remove(sort(v::reach (t, v)));;
因为我相信重复项将被有趣的“删除”删除,内部函数将使用列表 y 访问,而不是失去头脑的 t。然而事情确实 不按我的计划去。它仍然给我同样的结果。 要在其他条件下使用原始列表“g”进行函数访问,我该怎么办...?
reach <-- ([(1, 2); (2, 3); (3, 4); (4, 2); (2, 5)], 4)
reach <-- ([(2, 3); (3, 4); (4, 2); (2, 5)], 4)
reach <-- ([(3, 4); (4, 2); (2, 5)], 4)
reach <-- ([(4, 2); (2, 5)], 4)
reach <-- ([(1, 2); (2, 3); (3, 4); (4, 2); (2, 5)], 2)
(*I want function goes back to original list as the variable changes like above*)
【问题讨论】: