在列表 SML 中查找匹配的数字
Finding matching numbers in lists SML
我正在尝试用 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;
我认为在 in 语句中使用 |
在这里是不合法的,但我不知道如何在没有它的情况下递归地 运行 通过列表。
if both lists contain the same number (or multiple of the same number) [...]
您假设输入列表可能包含重复项,但您没有说明结果列表是否应包含重复项,如果是,它们的重数应该是多少。您的代码表明存在左偏: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
[...] those numbers are added to a new function
我不确定这里的确切含义。你不会把数字和函数加在一起,函数也没有可以添加东西的可变状态。也许你的意思是如果交集是非空的,一个函数被应用到这个非空的结果?
可能看起来像:
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
我正在尝试用 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;
我认为在 in 语句中使用 |
在这里是不合法的,但我不知道如何在没有它的情况下递归地 运行 通过列表。
if both lists contain the same number (or multiple of the same number) [...]
您假设输入列表可能包含重复项,但您没有说明结果列表是否应包含重复项,如果是,它们的重数应该是多少。您的代码表明存在左偏: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
[...] those numbers are added to a new function
我不确定这里的确切含义。你不会把数字和函数加在一起,函数也没有可以添加东西的可变状态。也许你的意思是如果交集是非空的,一个函数被应用到这个非空的结果?
可能看起来像:
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