我正在为课堂上的SML编程辅助工作并坚持一个问题。问题是: “编写一个ML函数,使用map,foldr或foldl来计算非空列表集的交集。在这里你可以假设集合表示为列表。对于这个问题,你可以使用辅助命名函数(例如,isMember)提示:非空的集合列表至少包含一个集合。“
这是我到目前为止所有人都指出我正确的方向我是SML的新手吗?
fun member(x,[]) = false
| member(x,L) =
if x=hd(L) then true
else member(x,tl(L));
fun intersect(L1,L2) = if tl(L1) = [] then L1
else if member(hd(L1),L2) = true then L1
else intersect(tl(L1),L2);
fun combine(L1) = if tl(L1) = [] then hd(L1)
else
foldr intersect [] L1;
我想要的代码是通过执行带有列表列表的combine函数开始的。它检查是否只有一个列表(即tl(L1)= []),如果是,则只打印第一个列表。如果它是假的我想调用foldr函数然后调用intersect函数。理论上,在foldr函数期间,我希望它检查第一个列表和第二个列表,并且仅保持哪些值相同,然后检查下一个列表以保留这些值并保持这样做直到它检查每个列表。完成之后,我希望它打印每个列表中的每个值(即集合的交集)。
我知道我的成员函数有效,并且组合函数完成它应该做的事情,我的问题是,交叉函数有什么问题,有人可以解释交集应该做什么吗?
我显然不想直接回答,这不是我在这里的意思。我需要帮助才能找到正确的答案。
答案 0 :(得分:3)
您的member
和combine
功能看似不错,但您需要更仔细地考虑intersect
功能。对于初学者,如果L1
是一个空列表,则会引发异常,因为tl
不会对空列表进行操作。想想你需要担心的三个案例:
L1
是nil hd(L1)
位于L2
hd(L1)
不在L2
弄清楚你需要做什么,并从那里开始。
答案 1 :(得分:0)
这是我的工作答案!
fun member(x,[]) = false
| member(x,L) =
if x=hd(L) then true
else member(x,tl(L));
fun intersect([],[]) = []
| intersect(L1,[]) = []
| intersect(L1,L2) = if member(hd(L2), L1) then hd(L2)::intersect(L1, tl(L2))
else intersect(L1, tl(L2));
fun combine(L1) = if L1 = [] then []
else if tl(L1) = [] then hd(L1)
else foldr intersect (hd(L1)) (tl(L1));
以下是一些测试用例。
combine([[1,2],[1,3],[1,4]]);
val it = [1] : int list
combine([[1,2,3],[1,8,9,3],[1,4,3,8,9]]);
val it = [1,3] : int list
combine([[1,2,3,8,9],[1,8,9,3],[1,4,3,8,9]]);
val it = [1,3,8,9] : int list