如何解决;“未解决的弹性记录”;在SML中的else if语句中?
我想找到当前给定节点直接或间接连接到的节点列表。 例如,我有一个节点列表:如何解决;“未解决的弹性记录”;在SML中的else if语句中?,sml,smlnj,Sml,Smlnj,我想找到当前给定节点直接或间接连接到的节点列表。 例如,我有一个节点列表: [1,2] 和元组列表,每个元组表示一条直边: [(1,5),(2,4),(4,6)] 所以,我要寻找的节点是 [1,2,5,4,6] 因为,1连接到5,2连接到4。然后,4连接到6。 要实现这一点,我需要两个队列和一个列表。每次发现新节点时,我们都会将新节点附加到队列和列表中。然后,我们移除队列的第一个节点,并转到下一个节点。如果新节点连接到队列的当前节点。然后,我们将新节点添加到队列和列表中 我们一直这样做,直
[1,2]
和元组列表,每个元组表示一条直边:
[(1,5),(2,4),(4,6)]
所以,我要寻找的节点是
[1,2,5,4,6]
因为,1连接到5,2连接到4。然后,4连接到6。
要实现这一点,我需要两个队列和一个列表。每次发现新节点时,我们都会将新节点附加到队列和列表中。然后,我们移除队列的第一个节点,并转到下一个节点。如果新节点连接到队列的当前节点。然后,我们将新节点添加到队列和列表中
我们一直这样做,直到队列为空并返回列表
现在,我有一个append函数,它将一个列表附加到另一个列表:
fun append(xs, ys) =
case ys of
[] => xs
| (y::ys') => append(xs @ [y], ys')
然后,我有一个名为getIndirectNodes的函数,它打算返回给定节点间接连接到的节点列表,但抛出“未解析的flex记录”。清单1和清单2应该有相同的项。但是,List1服务于队列,list2服务器作为要返回的列表
fun getIndirectNode(listRoleTuples, list1, list2) =
if list1 = []
then list2
else if hd(list1) = #1(hd(listRoleTuples))
then (
append(list1,#2(hd(listRoleTuples)) :: []);
append(list2,#2(hd(listRoleTuples)) :: []);
getIndirectNode(listRoleTuples,tl(list1),list2)
)
else
getIndirectNode(listRoleTuples,tl(list1),list2)
如果我删除else-If语句,它就可以正常工作。但是,这不是我想要做的。问题出在else-if语句中。我能做些什么来修复它呢?SML需要确切地知道元组的形状才能解构它。
您可以指定参数的类型-
listRoleTuples:(“a*”a)list
,但是使用模式匹配是一个更好的主意
(这段代码还有很多其他问题,但这就是你问题的答案。)看来你的一位同学在一次实验中遇到了这个确切的元组问题 在再次提出相同的问题之前,请确保浏览StackOverflow问答 对于获得间接节点,可以通过定点迭代来解决 首先得到所有直接节点,然后得到直接节点中的直接节点 递归地执行此操作,直到不再以这种方式出现新节点
fun getDirectNodes (startNode, edges) =
List.map #2 (List.filter (fn (node, _) => node = startNode) edges)
fun toSet xs =
... sort and remove duplicates ...
fun getReachableNodes (startNodes, edges) =
let
fun f startNode = getDirectNodes (startNode, edges)
val startNodes = toSet startNodes
val endNodes = toSet (List.concat (List.map f startNodes))
in
if startNodes = endNodes
then endNodes
else getReachableNodes (startNodes @ endNodes, edges)
end
这并不能准确地找到间接端点节点;它查找所有可由startNodes
直接或间接访问的节点,并包括startNodes
本身,即使它们本身无法直接或间接访问
我试图通过使用集合作为数据类型来简化这个练习;如果使用集类型的实际有效实现,例如使用平衡的二叉搜索树,则会更加整洁。通过向集合中添加元素,可以更容易地看到是否没有新节点,因为如果集合中已经包含元素,那么在添加元素之前和之后,它将与自身等价
当这有意义时,我尝试使用高阶函数。例如,给定一个列表,其中我希望对每个元素执行相同的操作,list.map
生成一个结果列表。但是由于我想做的事情,getDirectNodes(startNode,edges)
生成一个列表,然后list.map f
生成一个列表。因此,List.concat
将其压缩为一个列表
List.concat (List.map f xs)
这是一件非常常见的事情。然后
中的顺序是“附加这些列表并放弃结果,然后附加这些其他列表并放弃结果,然后递归”。您需要将结果传递给递归。您只使用了listRoleTuples
的第一个元素。试图同时在两个列表上递归通常是非常混乱的。尝试将问题分解,这样您只需要在一个列表上递归。(这个问题比乍看起来要棘手得多。考虑重复和循环。)注意,<代码>附录< /代码>已经存在作为<代码> @ <代码>运算符。