【问题标题】:Haskell rotate list of listsHaskell 轮换列表列表
【发布时间】:2020-08-19 15:16:33
【问题描述】:

我正在尝试在 Haskell 中实现以下函数,它是一个递归遍历,它接收一个 Int 和一个列表列表 [[Int]] 并将内部列表的元素向右移动而不改变大小列表。我能够以正确的顺序获得一个包含数字的列表,但我无法将它们重新插入到正确的子列表中。

shift_right::Int->[[Int]]->[[Int]]

示例 #1:

shift_right 1 [[1,2,3],[4,5,6]] => [[6,1,2],[3,4,5]]

示例 #2:

shift_right 3 [[],[1],[2,3],[4,5,6]] => [[],[4],[5,6],[1,2,3]]

【问题讨论】:

  • 我会通过 map length 来获取所有子列表的长度,concat-ing 来展平嵌套列表,移动整个展平列表,然后重新拆分展平的列表使用您在第一步中获得的长度移动列表。
  • 你能分享你到目前为止所做的事情吗?

标签: list haskell recursion functional-programming nested-lists


【解决方案1】:

假设空列表只出现在开头而不出现在中间,那么一种方法可能是,首先找到一种方法进行一次旋转,然后重复相同的操作nn 旋转.我认为我们可以为此使用mapAccumL

m = [[],[1],[2,3],[4,5,6]]
s l = es ++ (rem ++ ls) : lss
      where
      (rem, (ls:lss)) = mapAccumL shifter [] fs
      shifter a bs    = ([last bs], a ++ (init bs))
      (es,fs)         = span (== []) l              -- split empties and fulls

λ> s m
[[],[6],[1,2],[3,4,5]]

λ> s [[],[6],[1,2],[3,4,5]] -- carry from previous answer
[[],[5],[6,1],[2,3,4]]

λ> s [[],[5],[6,1],[2,3,4]] -- carry from previous answer
[[],[4],[5,6],[1,2,3]]

所以现在......既然你根本没有尝试,你有责任想出一个代码来调用这个函数(或这个函数的一部分)nn 旋转 提示:最好不要连接空。

【讨论】:

  • 这个假设似乎很武断。一种声明性方法可以是从线性供应的值中填充任何给定的(树状)结构,从同一结构的边缘(即扁平列表)获取(移动)。 (我answered 一次或两次这样的事情,在 Scheme/pseudo-Haskell 中使用 CPS 代码)。 :) 我认为这种方法也适用于此。
  • @WillNess 我的假设基于给定的测试用例按长度排序,但是是的,你仍然可以称它为任意的。同意通过迭代原始嵌套列表来展平、旋转和重建嵌套结构是一个好主意,而且很可能效率更高。
猜你喜欢
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
相关资源
最近更新 更多