【问题标题】:How to add elements to a list every nth round?如何每第 n 轮将元素添加到列表中?
【发布时间】:2018-08-11 16:35:54
【问题描述】:

我需要 编写一个int * 'a * 'a list -> 'a lst 类型的函数separate 使得 separate (k, x, l) 返回在列表l 的每个k 元素之后插入元素x 的列表l(从 列表的末尾)。例如,separate (1, 0, [1,2,3,4]) 应该返回 [1,0,2,0,3,0,4]separate (3, 0, [1,2,3,4]) 应该返回 [1,0,2,3,4]

到目前为止,这就是我所拥有的,但它会导致错误。谁能帮帮我?

fun separate (k: int, x: 'a, l: 'a list) : 'a list =
   let val count:int = k
    in foldr(
        (fn (h, t) =>
            if count = 0
            then count := 1 in
               x::h::t 
            else count = count + 1 : int
                h::t
            )

【问题讨论】:

  • count := 1 in 不是做let val count = 1 in 之类的事情的方法,而且,你似乎在思考。您是否要变异计数?
  • 是的,每次我查看列表中的一个元素时,我都会尝试减少计数,从后面开始一直移动到开头。一旦计数为零,我们就知道我们在我们需要的位置,然后将元素插入到列表中的那个位置。我也很难不去思考。没有 foldl/foldr 有没有办法做到这一点?我使用了其中任何一种,因为它似乎可以简化问题。
  • 值在纯函数式编程中是不可变的。 “减少计数”是什么意思?如果您想做类似的事情,您需要将count 设为函数(主函数或辅助函数)的参数之一。

标签: list sml ml mosml


【解决方案1】:

其实逻辑是很对的,但是由于不可变性,应该通过将改变的状态传递给foldr的另一个迭代来实现:

fun separate (k: int, x: 'a, l: 'a list) : 'a list =
  #2 (foldr (fn (h, (count, t)) =>
      if count = 0
      then (k - 1, h::x::t)
      else (count - 1, h::t)
    ) (k, []) l);

因此,我们不是将count作为变量初始化,而是使用元组(k, [])初始化foldr(其中kcount的初始值,[]是结果列表),然后减少计算迭代的每一步。

【讨论】:

    猜你喜欢
    • 2022-10-31
    • 2023-01-16
    • 2015-01-12
    • 2021-10-04
    • 2022-01-25
    • 2018-03-09
    • 2022-01-05
    • 2015-08-01
    • 1970-01-01
    相关资源
    最近更新 更多