List SML函数包含两个列表,返回XOR---fixed

List SML函数包含两个列表,返回XOR---fixed,list,sml,xor,List,Sml,Xor,是否有人能够为SML中的函数提供任何建议,该函数将接受2个列表并返回它们的异或,因此如果您有列表[a,b,c,d],[c,d,e,f],函数将返回[a,b,e,f] 我试着用两个函数来实现它,但即使这样也不能正常工作 fun del(nil,L2) = nil |del(x::xs,L2)= if (List.find (fn y => y = x) L2) <> (SOME x) then del(xs, L2) @ [x] else del(xs, L2); fun x

是否有人能够为SML中的函数提供任何建议,该函数将接受2个列表并返回它们的异或,因此如果您有列表[a,b,c,d],[c,d,e,f],函数将返回[a,b,e,f]

我试着用两个函数来实现它,但即使这样也不能正常工作

fun del(nil,L2) = nil
|del(x::xs,L2)=
if (List.find (fn y => y = x) L2) <> (SOME x) then
del(xs, L2) @ [x]
else 
del(xs, L2);

fun xor(L3,L4) = 
rev(del(L3,L4)) @ rev(del(L4,L3));
fundel(nil,L2)=nil
|del(x::xs,L2)=
如果(List.find(fny=>y=x)L2)(一些x)那么
del(xs,L2)@[x]
其他的
del(xs,L2);
趣味异或(L3,L4)=
rev(del(L3,L4))@rev(del(L4,L3));

最简单的方法是从每个列表中筛选出重复项,然后将两个结果列表连接起来。使用List.filter,您可以删除作为另一个列表的成员(List.exists)的任何元素

然而,这是相当低效的,下面的代码更像是一个在现实生活中如何不这样做的示例,尽管它“功能上”看起来很好:)

这应该是一个更好的解决方案,仍然保持简单。它使用SML/NJ特定的ListMergeSort模块对组合列表
a@b
进行排序

fun symDiff1 a b =
    let
      val ab' = ListMergeSort.sort op> (a @ b)
      (* Remove elements if they occur more than once. Flag indicates whether x
         should be removed when no further matches are found *)
      fun symDif' (x :: y :: xs) flag  =
          (case (x = y, flag) of
             (* Element is not flagged for removal, so keep it *)
             (false, false) => x :: symDif' (y :: xs) false
             (* Reset the flag and remove x as it was marked for removal *)
           | (false, true) => symDif' (y::xs) false

             (* Remove y and flag x for removal if it wasn't already *)
           | (true, _) => symDif' (x::xs) true)
        | symDif' xs _ = xs
    in
      symDif' ab' false
    end

然而,这仍然有点愚蠢。由于排序函数遍历组合列表中的所有元素,因此它也应该是“负责”删除重复项的函数。

您的尝试似乎几乎正确,只是
fn x=>x=x
没有意义,因为它总是返回true。我想你想要的是
fny=>y=x

还有几句话:

  • 您可以使用更接近所需的
    List.filter
    替换使用的
    List.find

  • 不要对递归步骤执行
    del(xs,L)@[x]
    。添加到列表末尾的成本与第一个列表的长度成线性关系,因此如果在每个步骤中都添加,那么函数将具有二次运行时间。改为执行
    x::del(xs,L)
    ,这也允许您在最后删除列表反转

  • 这里所谓的“XOR”通常称为对称差分,至少对于类似集合的结构是这样


您能否澄清两个列表的XOR的确切含义?Thank.exclusive or,如果您有列表[a,b,c,d],[c,d,e,f],那么函数返回[a,b,e,f],换句话说,您想删除两个列表之间的重复项吗?是的,如果项目都在两个列表中,它不应该进入最终列表。只有元素和唯一的项目才能进入最终列表。您应该返回一个代码示例。现在有很多SML问题需要回答,感觉就像一场梦:)。@pad,呵呵。正如承诺的那样,虽然有点晚了。稍后我将编写一个“更好”的示例。我将调用辅助函数
diff
not
filter
)不过,您的
symDiff1
是一个完全不同的函数。除了对结果中的元素进行排序(因此仅限于int列表),它还删除了每个参数的重复项,而另一个参数则没有。谢谢你们的帮助,只为我更改了匿名函数。谢谢。在我对高级函数了解很多之前,我一直在玩弄它们。现在我提前阅读,这就更有意义了。
fun symDiff1 a b =
    let
      val ab' = ListMergeSort.sort op> (a @ b)
      (* Remove elements if they occur more than once. Flag indicates whether x
         should be removed when no further matches are found *)
      fun symDif' (x :: y :: xs) flag  =
          (case (x = y, flag) of
             (* Element is not flagged for removal, so keep it *)
             (false, false) => x :: symDif' (y :: xs) false
             (* Reset the flag and remove x as it was marked for removal *)
           | (false, true) => symDif' (y::xs) false

             (* Remove y and flag x for removal if it wasn't already *)
           | (true, _) => symDif' (x::xs) true)
        | symDif' xs _ = xs
    in
      symDif' ab' false
    end