在交替使用2个列表元素时,我的SML代码一直遇到困难。我必须创建一个最终列表,该列表将包含2个相同大小的列表并替换其元素。一个例子是
alternate([1,3,5],[2,4,6]) = [1,2,3,4,5,6]
我不确定代码在哪里出错。任何帮助将不胜感激。这是我目前拥有的代码
fun alternate2([],y) = []
| alternate2(a::x,y) =
if length listx = length listy then
if countListx = countListy then (List.nth(listx, countListx)::alternate2(x,y); count(countListx))
else if countListx <> length listx - 1 then
if countListy < countListx then (alternate2(x, a::y); count(countListy))
else alternate2(x,y)
else alternate2(x,y)
else alternate2(x,y);
答案 0 :(得分:0)
您可以完全使用模式匹配和递归来完成此操作,而无需使用length
,if-then-else
或=
。由于此练习非常小,因此我很难在不给出答案的情况下给出字面提示,因此我将尝试以类似的方式解决类似的问题:
给定一个函数f : 'a * 'b -> 'c
和两个列表xs : 'a list
和ys : 'b list
,我可以通过将函数'z list
应用于每对{ {1}},其中每个f
来自(x, y)
,每个x
来自xs
。如果一个列表比另一个列表长,我将丢弃多余的元素。
y
由于后三种情况下的响应都相同,所以我也可以这样写:
ys
您的函数fun zipWith (f, x::xs, y::ys) = f (x, y) :: zipWith (f, xs, ys)
| zipWith (_, [], []) = [] (* end of both lists *)
| zipWith (_, xs, []) = [] (* xs is longer, discard it *)
| zipWIth (_, [], ys) = [] (* ys is longer, discard it *)
的行为非常相似,不同之处在于每一步的计算都不是fun zipWith (f, x::xs, y::ys) = f (x, y) :: zipWith (f, xs, ys)
| zipWith (_, _, _) = [] (* either one or both lists are empty *)
,因为您自然没有alternate2
。另外,在您使用f (x, y)
的情况下,每对f
和x
不应导致单个元素,而应连续两个元素。
y
答案 1 :(得分:0)
您可以通过几种方法来执行此操作,但是我建议一种方法与您的函数类型('a list * 'a list -> 'a list
)相符,并且还严格执行以下约束:两个输入列表必须属于大小相同。
fun interleave ([],[]) = []
| interleave (x::xs,y::ys) = x :: y :: interleave (xs,ys);
此功能通过模式匹配起作用。在最简单的情况下,它需要两个空列表并返回一个空列表。否则,它应该期望有两个列表,每个列表中至少有一个项目。
如果两个列表以不同的长度传递,则由于([], y::ys)
和(x::xs, [])
的情况与任何指定的模式都不匹配,将引发匹配异常。
这意味着编译器可能会产生警告(warning: Matches are not exhaustive.
),但这是设计使然。
还可以创建一个显式异常,导致类似以下内容:
exception DifferentLengthsException;
fun interleave ([],[]) = []
| interleave (x::xs,y::ys) = x :: y :: interleave (xs,ys)
| interleave (xs,ys) = raise DifferentLengthsException;
如果将两个不同长度的列表传递给这些函数中的任何一个,则会引发异常(以下是示例堆栈跟踪)。
val x = interleave ([1,3,5,7],[2,4,6]);
val x = 1 :: 2 :: interleave ([3,5,7], [4,6]);
val x = 1 :: 2 :: 3 :: 4 :: interleave ([5,7], [6]);
val x = 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: interleave ([7], []);
Exception- Match raised