在列表SML中查找匹配的数字

时间:2018-01-31 02:46:52

标签: list recursion sml smlnj

我正在尝试在SML中编写一个函数,其中有两个列表被传递到函数中,如果两个列表包含相同的数字(或相同数字的多个),则这些数字将被添加到新函数中。

fun shared([], []) = []
    let 
        val list = []
    in
        shared(x::xs, y) = if x = y then x::list else shared(xs,y)
    end

我的思维过程是,如果x和y相等,则x将被添加到列表中,该列表将包含两个原始列表中共享的所有数字。

编辑:新代码

fun append([], L) = L
    | append(x::rest, L) = x::append(rest, L);

fun shared([], y) = 
    let 
        val list = []
    in
        | shared(y, x::xs) = if y = x then append(list, x)
                                    else shared(y,xs)
    end;

我不认为在这里使用|是合法的,但我不知道如何在没有它的情况下以递归方式运行列表。

1 个答案:

答案 0 :(得分:0)

  

如果两个列表包含相同的数字(或相同数字的倍数)[...]

您认为输入列表可能包含重复项,但您不能说结果列表是否应包含重复项,如果是,那么它们的多样性应该是多少。您的代码建议左偏:xs中的重复项应重复xs中的重复次数,而不管ys中出现多少次重复;这似乎是无意识和不受欢迎的。

如果您希望重复发生多次,您应该坚持多重性的multiset intersection定义。

在下面的答案中,我假设您只希望数字出现在结果中一次,即使它们在任一输入列表中出现多次。但是,理想情况下,在这种情况下,您对不允许重复的集合使用数据类型。

我首先找到两个列表之间的集合交集:

(* Remove duplicates in ''a list. O(n^2) *)
fun nub [] = []
  | nub (x::xs) = x :: nub (List.filter (fn y => x <> y) xs)

(* Determine membership of x in ys. O(n) *)
fun isElem (x, ys) = List.exists (fn y => x = y) ys

(* Find intersection of xs, ys, remove duplicates. O(n^2) *)
fun intersect (xs, ys) = nub (List.filter (fn x => isElem (x, ys)) xs)

这是一个使用它的例子:

- intersect ([0,0,1,1,2,2,3,4], [1,1,2,3,3,5,6,6]);
> val it = [1, 2, 3] : int list
  

[...]这些数字被添加到新功能

我不确定这里到底是什么意思。您不能将数字和功能一起添加,并且功能不具有可添加内容的可变状态。也许你的意思是如果交集是非空的,那么一个函数应用到这个非空的结果?

这可能看起来像:

fun sum xs = foldl op+ 0 xs

fun printIntersectSum (xs, ys) =
    case intersect (xs, ys) of
         []  => print "Nothing to see; move along!\n"
       | res => print ("Sum of intersection: " ^ Int.toString (sum res) ^ "\n")

这是一个使用它的例子:

- printIntersectSum ([0,0,1,1,2,2,3,4], [1,1,2,3,3,5,6,6]);
The sum of the intersection is: 6
> val it = () : unit