【问题标题】:Creating an intersection and difference in ML New Jersey在 ML New Jersey 中创建交集和差异
【发布时间】:2020-01-15 13:08:14
【问题描述】:

使用前面构造的函数contains,编写一个函数intersection,它接受两个列表(建模集)并返回一个列表,该列表是两个集合的交集。所以

intersection([1, 2, 3], [1, 3])

将返回[1, 3]

使用前面构造的函数contains,编写一个函数difference,它接受两个列表并返回一个列表,该列表对第一个集合与第二个集合(集合A - 集合B)的差异进行建模。

我已经创建了下面的代码contains,现在我的目标是创建intersectiondifference 函数。

fun contains(x, []) = false
  | contains(x, y::rest) = 
    if x = y
    then true 
    else contains(x, rest);

fun intersection([], y) = []
  | intersection(x, y) = if x = y
   then [x,y]
   else [];;

尝试一下:

- intersection([1, 2], [2, 3]);
val it = [] : int list list

【问题讨论】:

  • 需要递归,需要研究集合交集的定义。

标签: sml smlnj ml


【解决方案1】:

至于你的contains功能,可以稍微改进一下:

fun contains(x, []) = false
  | contains(x, y::rest) = 
    x = y orelse contains(x, rest)

if P then true else QP orelse Q相同。

高阶标准库解决方案是写

fun contains (x, ys) = List.exists (fn y => x = y) ys

但如果练习是为了证明对基本递归的理解,则最好使用前者。

至于您的intersection 函数,似乎无论您设法创建contains,您都没有应用相同的列表递归原则。您比较x = y,但这里xy 是列表,而不是单个元素。而在contains 中,x 是列表/集合中的单个值,y 是列表/集合y::rest 的第一个元素。

因此,您可能应该开始使用类型注释每个参数,或者以您不会怀疑它应该代表什么的方式命名它。对于intersection,规则是您只需要同时属于两个列表/集合的元素。

例如:

fun intersection (xs, ys) = ...

或带有注释的类型:

fun intersection (xs : ''a list, ys : ''a list) = ...

您可能认为您需要通过模式匹配xsys 上的空/非空列表来对列表使用递归。我在这里选择了xs,因为它恰好是第一个参数,但这是任意的:

fun intersection ([],    ys) = ...
  | intersection (x::xs, ys) = ...

或带有注释的类型:

fun intersection ([]    : ''a list, ys : ''a list) = ...
  | intersection (x::xs : ''a list, ys : ''a list) = ...

那你可以问问自己:

  1. 空列表/集与ys 的交集是什么?
  2. xx::xsys 交集的一部分吗?
  3. 还有哪些其他元素可能是此交集的一部分(递归)?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多