简体   繁体   English

Haskell列表理解0和1

[英]Haskell list comprehension 0's and 1's

I am trying to write a function 我正在尝试编写一个函数

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

that returns a list of n integers, all 0 's, except for the v th element, which needs to be a 1 . 返回一个n整数的列表,全部为0 ,除了第v个元素,需要为1

For instance, 例如,

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

I am new to Haskell and having a lot of difficulty with this. 我是Haskell的新手,对此有很多困难。 In particular I can't figure out how to make it repeat 0 's. 特别是我无法弄清楚如何让它重复0 I understand the concept of building a list from let's say [1..n] , but I just get [1,2,3,4,5] 我理解构建列表的概念,比如说[1..n] ,但我得到[1,2,3,4,5]

Any help with this would be greatly appreciated. 任何有关这方面的帮助将不胜感激。 Thank you. 谢谢。

尝试:

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

Here a "monadic" solution: 这是一个“monadic”解决方案:

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

The replicate function repeats a given value a number of times, eg replicate (v-1) 0 gives a list of v-1 zeros. replicate函数多次重复给定值,例如replicate (v-1) 0给出v-1零的列表。 The uncurry is used to modify the replicate in order to accept a tuple instead of two single arguments. uncurry用于修改replicate以接受元组而不是两个单个参数。 The funny operator >>= is the heart of a monad; 有趣的算子>>=是monad的核心; for lists it is the same as concatMap with flipped arguments. 对于列表,它与带有翻转参数的concatMap相同。

With a comprehensive list : 有一个全面的清单:

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

Or using fromEnum (thanks dave4420) 或者使用fromEnum (感谢dave4420)

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

这应该也有效:

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

And yet another solution, recursively building up the list: 还有另一个解决方案,递归地构建列表:

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

And a more readable one, where zeros are "taken": 并且更具可读性,其中零被“采用”:

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

A simple recursive loop with two temporary variables c and lst . 一个带有两个临时变量c和lst的简单递归循环。 c is for counting and lst is list which we have to return. 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 ] )

~
~

the fun with haskell is that it let's you write your program very much the way you would express the algorithm. haskell的乐趣在于它让你编写程序非常像你表达算法的方式。 So try: 所以尝试:

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

At first you create a list from 1,2 to n. 首先,您创建一个从1,2到n的列表。 Then you check if the number is divisible by v, if it is, 1 is inserted in the output list, if not 0. 然后检查数字是否可以被v整除,如果是,则在输出列表中插入1,如果不是0。

Examples: 例子:

> 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 HTH Chris

I like to demonstrate a top down approach, based on Chris's solution: 我想基于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

This style emphasizes the idea in functional programming that one writes down what a certain value like row nv is supposed to be , rather than trying to write down what a function does . 这种风格强调了函数式编程的想法,一个写下什么样的一定值row nv 应该是 ,而不是试图写下的功能是什么。 In reminiscence of a well known joke about the lesser known pragramming language Sartre one could say that in pure functional programming functions do nothing, they just are . 回忆一个关于鲜为人知的语法萨特的一个众所周知的笑话,人们可以说,在纯粹的函数编程函数中什么都不 ,它们就是这样

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM