来自2个列表的交替元素SML

时间:2019-11-21 23:46:24

标签: sml

在交替使用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);

2 个答案:

答案 0 :(得分:0)

您可以完全使用模式匹配和递归来完成此操作,而无需使用lengthif-then-else=。由于此练习非常小,因此我很难在不给出答案的情况下给出字面提示,因此我将尝试以类似的方式解决类似的问题:

给定一个函数f : 'a * 'b -> 'c和两个列表xs : 'a listys : '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)的情况下,每对fx不应导致单个元素,而应连续两个元素。

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