哈斯克尔。列表列表出现问题

时间:2017-06-13 18:42:04

标签: list haskell functional-programming

我有Int的列表列表,我需要在列表列表的最后一个列表中添加Int值。我怎样才能做到这一点?我的尝试低于

f :: [[Int]] -> [Int] -> Int -> Int -> Int -> [[Int]]
f xs [] cur done total = [[]]
f xs xs2 cur done total = do 
  if total >= length xs2 then 
    xs
  else 
    if done == fib cur then
      f (xs ++ [[]]) xs2 (cur + 1) 0 total
    else
      f ((last xs) ++ [[xs2!!total]]) xs2 cur (done + 1) (total + 1)

问题是: 我们有一个Int A列表
我们需要在N列表B_1 ,..., B_n上对其进行调整,B_i的长度为第i个斐波纳契数。
如果我们的代码中有[1 , 2 , 3 , 4 , 5 , 6 , 7]xs2)列表 结果应为[[1] , [2] , [3 , 4] , [5 , 6 , 7]]

3 个答案:

答案 0 :(得分:3)

处理这类问题的简单方法是将问题分解为子问题。在这种情况下,您想要更改列表中的最后一项。您想要更改它的方式是向其添加项目。

首先让我们解决更改列表的最后一项的问题。我们将通过将函数应用于最后一项而不是任何其他项来完成此操作。

onLast :: [a] -> (a -> a) -> [a]
onLast xs f = go xs
  where
    go [] = []
    go [x] = [f x]
    go (x:xs) = x:go xs

您想通过添加额外的值来更改列表中的最后一项,您可以使用(++ [value])来执行此操作。

将两者与您要添加的值(xs2!!total)相结合,我们得到

(onLast xs (++ [xs2!!total]))

答案 1 :(得分:0)

你的方法使用do块,这有点奇怪,因为do块通常用于 monads 。此外,还不清楚curdonetotal正在做什么。此外,您使用(!!) :: [a] -> Int -> alength :: [a] -> Int。这些函数的问题是它们在 O(n)中运行,因此它也使代码效率低下。

根据更改的规范,您希望拆分列表中的列表,其长度为 Fibonacci数字。在这种情况下,签名应为:

f :: [a] -> [[a]]

因为输入时会给出一个数字列表,作为输出,您将返回一个数字列表。然后我们可以将其实现为:

f :: [a] -> [[a]]
f = g 0 1
    where g _ _ [] = []
          g a b xs = xa : g b (a+b) xb
              where (xa,xb) = splitAt b xs

这会产生:

*Main> f [1,2,3,4,5,6]
[[1],[2],[3,4],[5,6]]
*Main> f [1,2,3,4,5,6,7]
[[1],[2],[3,4],[5,6,7]]
*Main> f [1,2,3,4,5,6,7,8]
[[1],[2],[3,4],[5,6,7],[8]]
*Main> f [1,2,3,4,5,6,7,8,9]
[[1],[2],[3,4],[5,6,7],[8,9]]

代码的工作方式如下:我们声明f = g 0 1,因此我们将f的参数传递给g,但g也获得了0和a 1(第一个斐波纳契数)。

每次迭代g检查我们是否到达列表的末尾。如果是这样,我们也返回一个空列表。否则,我们确定最后一个Fibonacci数(b),并使用splitAt获取我们处理的列表的第一个b元素,以及余数。然后我们将第一部分作为列表的头部发出,对于尾部,我们计算下一个斐波纳契数,并将其传递给g,尾部为splitAt

答案 2 :(得分:0)

f :: [[Int]] -> Int -> [[Int]]                                                                                                                                                                                                   
f [] _ = []                                                                                                                                                                                                                      
f xs i = (take n xs) ++ [[x + i | x <- last xs]]                                                                                                                                                                                 
    where n = (length xs) - 1                                                                                                                                                                                                    
          last = head . (drop n) 

例如,

*Main> f [[1, 2, 3], [], [4, 5, 6]] 5
[[1,2,3],[],[9,10,11]]
*Main> f [[1, 2, 3]] 5
[[6,7,8]]
*Main> f [] 3