我试图获取pascal列表中每个列表中的第k行。例如,pascal 4将获得每行中的第4个元素。所以它将返回1,4,10,20 ...等我理解如何构造一个无限的pascal列表,这是下面的输出,但我不确定如何在每个嵌套列表中获取第n个元素。有什么建议?我正在考虑使用地图,但我不一定在这里映射一个功能,这让我有点失望。谢谢。
// im trying to get pascal k to return the nth element of every row in the triangle
pascal n = map(\n -> ??) take n pascal
pascal_infite = [1] : map (\l -> zipWith (+) (l ++ [0]) (0:l)) pascal_infinite
答案 0 :(得分:2)
获取第k行:
>>> pascal_infinite !! 4
[1,4,6,4,1]
从[0..k]
获取所有行:
>>> map (pascal_infinite !!) [0..4]
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
要从[0..k]
快速获取所有行:
>>> take (4+1) pascal_infinite
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
哎呀,误读了一下这个问题。为了得到你所要求的东西,如果你担心速度,你应该构建一个好的旧n choose k
公式或类似的东西。
如果这只是一个练习,无视速度,这是一种方式:
pascal n = map (!! n) $ drop n pascal_infinite
然后简单地抽取几个第四个元素:
>>> take 8 $ pascal (4-1)
[1,4,10,20,35,56,84,120]
答案 1 :(得分:1)
这基本上是一个iterate :: (a -> a) -> a -> [a]
函数,你有一个状态,每次更新状态,你就会产生一个元素列表。
作为迭代函数,我们基本上希望使用前一个列表zipWith (+)
和xs
执行(0:xs)
,但我们会继续迭代,直到两个列表都用完为止。我们可以为此实现zipWithLongest
:
zipWithLongest :: a -> b -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithLongest x0 y0 f = go
where go (x:xs) (y:ys) = f x y : go xs ys
go [] t = map (f x0) t
go t [] = map (flip f y0) t
现在我们可以使用:
生成列表import Control.Monad(ap)
pascalTriangle :: Num n => [[n]]
pascalTriangle = iterate (ap (zipWithLongest 0 0 (+)) (0:)) [1]
我们可以使用(!!) :: [a] -> Int -> a
索引列表。但请注意,由于两个原因,这通常是一种反模式:
我们知道 Pascal三角形的每一行都包含一个比前一行更多的元素。所以 k -th行包含 k 元素。如果我们想获得每个子列表中的k
- 元素,那么我们应该首先忽略所有不具有k
个元素的列表。因此,我们使用drop k
删除列表的第一个k
- 元素,然后使用map (!! k)
来获取我们不过滤的每个子列表的k
个元素
所以我们可以编写一个函数:
kThPascalTriangle :: Num n => Int -> [n]
kThPascalTriangle k = map (!! k) (drop k pascalTriangle)