Haskell列表理解0和1

时间:2011-10-05 07:58:21

标签: list haskell

我正在尝试编写一个函数

row :: Int -> Int -> [Int]
row n v

返回n个整数的列表,所有0个,但v元素除外,它必须是1

例如,

row 0 0 = []
row 5 1 = [1,0,0,0,0]
row 5 3 = [0,0,1,0,0]

我是Haskell的新手,对此有很多困难。特别是我无法弄清楚如何重复0。我理解构建列表的概念,比如说[1..n],但我得到[1,2,3,4,5]

对此的任何帮助将不胜感激。谢谢。

8 个答案:

答案 0 :(得分:16)

尝试:

let row n v = map (\x -> if x == v then 1 else 0) [1..n]

答案 1 :(得分:11)

这是一个“monadic”解决方案:

row n v = [(v-1, 0), (1, 1), (n-v, 0)] >>= (uncurry replicate)

replicate函数重复给定值多次,例如replicate (v-1) 0列出了v-1个零。 uncurry用于修改replicate以接受元组而不是两个单个参数。有趣的算子>>=是monad的核心;对于列表,它与带有翻转参数的concatMap相同。

答案 2 :(得分:8)

有一个全面的清单:

 row n v = [if x == v then 1 else 0 | x <- [1..n]]

或使用fromEnum(感谢dave4420)

 row n v = [fromEnum (x == v) | x <- [1..n]]

答案 3 :(得分:3)

这也应该有效:

row n v = replicate (v-1)­ 0 ++ [1] ++ repl­icate (n-v)­ 0

答案 4 :(得分:1)

又一个解决方案,以递归方式构建列表:

row :: Int -> Int -> [Int]
row 0 _ = []
row n 1 = 1 : (row (n-1) 0)
row n m = 0 : (row (n-1) (m-1))

更具可读性,其中零被“采取”:

row :: Int -> Int -> [Int]
row 0 _ = []
row n m = take (m - 1) zeros ++ [1] ++ take (n - m) zeros
    where zeros = (iterate id 0)

答案 5 :(得分:0)

一个带有两个临时变量c和lst的简单递归循环。 c用于计数,lst是我们必须返回的列表。

row :: Int -> Int -> [ Int ]
row 0 0 = []
row n v = rowHelp n v 1 [] where
    rowHelp n v c lst
            | c > n = lst
            | v == c = rowHelp n v ( c + 1 ) ( lst ++ [ 1 ] )
            | otherwise = rowHelp n v ( c + 1 ) ( lst ++ [ 0 ] )


答案 6 :(得分:0)

使用haskell的乐趣在于,它让你编写程序非常像表达算法的方式。所以试试:

row n v = [if (x `mod` v==0) then 1 else 0  | x <- [1..n] ]

首先,您创建一个从1,2到n的列表。 然后检查数字是否可以被v整除,如果是,则在输出列表中插入1,如果不是0。

示例:

> row 0 0
[]
> row 5 1
[1,0,0,0,0]
> row 5 3
[0,0,1,0,0]
> row 15 3
[0,0,1,0,0,1,0,0,1,0,0,1,0,0,1]

HTH Chris

答案 7 :(得分:0)

我喜欢根据Chris的解决方案展示一种自上而下的方法:

row n v = result           
    where
        result = take n numbers        -- our result will have a length of n
        numbers = map trans [1,2,..]   -- and is some transformation of
                                       -- the list of natural numbers
        trans e
           | e `mod` v == 0  = 1       -- let every v-th element be 1
           | otherwise       = 0       -- 0 otherwise

这种风格强调函数式编程中的一个想法,即写下像row n v 这样的某个值应该是,而不是写下函数的 。回想起一个众所周知的关于鲜为人知的编程语言萨特的笑话,人们可以说,在纯粹的函数式编程函数什么都没有,他们只是