用零填充列表的末尾

时间:2017-01-31 20:01:59

标签: sml smlnj ssml sysml

我们有一个类似[13,7,8,4]的列表和一个 N 的数字。我们想在该列表的末尾插入元素(一些零),其数量为“N mod ListSize”。假设 N = 6 并且根据列表,ListSize是4.所以6 mod 4 = 2然后我必须在其中插入2个零,如下所示:[13,7,8,4,0,0]

我们如何通过SML中的函数执行此操作?

1 个答案:

答案 0 :(得分:1)

列表末尾的填充是 O(n)操作。如果orig是您的原始列表,并且zeroes是您填充的零,orig @ zeroes涉及将orig的每个元素预先添加到zeroes

组合方法是首先找到零的数量,然后创建那些零,然后附加它们。

fun numberOfZeroes xs n = n mod List.length xs

fun replicate x 0 = []
  | replicate x n = x :: replicate x (n-1)

fun zeroes xs n = replicate 0 (numberOfZeroes xs n)

fun pad xs n = xs @ zeroes xs n

您可以在追加零的同时计算xs的长度来保存一次遍历(与单独的length / @不同)。组合函数可能如下所示:

fun pad xs n =
    let fun pad' (x::xs) count = x :: pad' xs (count + 1)
          | pad' [] count = replicate 0 (count mod n)
    in pad' xs 0 end

但是,此函数不是尾递归的,因此对于大xs,它可能会耗尽堆栈空间。 (replicate也不是,但只会产生长度为 N 的列表。)为了使其以递归方式,无论如何,必须遍历列表两次。此外,用较不复杂的函数构建复杂函数会降低认知负荷。

最后,您对问题的描述非常好。下次对问题进行类似清晰的描述时,请尝试编写正确实现将通过的测试。例如。你描述的测试是:

val test1 = pad [13,7,8,4] 6 = [13,7,8,4,0,0]

除了一个测试之外,添加更多,直到您定义了所有角落情况。例如:

val test2 = pad [13,7,8,4] 4 = ?