【发布时间】:2017-10-01 05:04:53
【问题描述】:
我正在尝试编写一个 SML 函数,该函数在 listViolations(L1, L2) 中返回结果数组。我特别想相互交叉引用每个元素 O(n^2),并检查选择是否相互冲突。可视化:[[1, 2], [2, 3]] 是选项 1,[[3, 2], [2, 1]] 是选项 2。我会这样调用 listViolations:listViolations([[[1, 2], [2, 3]], [[3, 2], [2, 1]]])。
行动计划是:
fun listViolations(L1, L2) =
if L1 = [] orelse L2 = []
then 0
else totalViolations(transitive_closure(hd(L1)),path(hd(L2)))::[] @ listViolations(L1, tl(L2))::[] @ listViolations(tl(L1), L2)::[];
在这里,我正在检查两个列表的头部,并递归地传递两个列表的尾部,希望创建如下内容:[3, 0 , 0]。
虽然我在声明函数时遇到了这个错误:
stdIn:726.5-728.136 Error: types of if branches do not agree [overload conflict]
then branch: [int ty]
else branch: int list
in expression:
if (L1 = nil) orelse (L2 = nil)
then 0
else totalViolations (transitive_closure <exp>,path <exp>) ::
nil @ listViolations <exp> :: <exp> @ <exp>
我在下面提供了所有其他功能以表明它们没有任何问题,我只是想知道我是否做错了什么。我知道一个事实,
- totalViolations(transitive_closure(hd(L1)),path(hd(L2)))
- listViolations(L1, tl(L2))::[]
- listViolations(tl(L1), L2)::[];
返回整数。如何从中列出列表并在此函数中返回?提前谢谢你。
//[1, 2] , [1, 2, 3] = 0
//[3, 2] , [1, 2, 3] = 1
fun violation(T, P) =
if indexOf(hd(T), P) < indexOf(hd(tl(T)), P) then 0
else 1;
//[[1, 2], [2, 3]] , [1, 2, 3] = 0
//[[3, 2], [2, 1]] , [1, 2, 3] = 2
fun totalViolations(TS, P) =
if TS = [] then 0
else violation(hd(TS), P) + totalViolations(tl(TS), P);
//[[1, 2],[2, 3]] -> [1, 2, 3]
fun path(L) =
if L = [] orelse L =[[]]
then []
else union(hd(L),path(tl(L)));
// [[1, 2],[2, 3]] -> [[1, 2],[2, 3], [1, 3]]
fun transitive_closure(L) = union(L, remove([], closure(L, L)));
附加代码:
fun len(L) = if (L=nil) then 0 else 1+length(tl(L));
fun remove(x, L) =
if L = [] then []
else if x = hd(L) then remove(x, tl(L))
else hd(L)::remove(x, tl(L));
fun transitive(L1, L2) =
if len(L1) = 2 andalso len(L2) = 2 andalso tl(L1) = hd(L2)::[]
then hd(L1)::tl(L2)
else [];
fun closure(L1, L2) =
if (L1 = [[]] orelse L2 = [[]] orelse L1 = [] orelse L2 = [])
then [[]]
else if len(L1) = 1 andalso len(L2) = 1
then transitive(hd(L1), hd(L2))::[]
else
union( union(closure(tl(L1), L2), closure(L1, tl(L2))), transitive(hd(L1), hd(L2))::[]);
【问题讨论】: