Haskell 列表理解 0 和 1

发布于 2024-12-07 21:03:46 字数 425 浏览 1 评论 0原文

我正在尝试编写一个

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]

任何帮助我们将不胜感激。谢谢。

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 vth element, which needs to be a 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. In particular I can't figure out how to make it repeat 0's. I understand the concept of building a list from let's say [1..n], but I just get [1,2,3,4,5]

Any help with this would be greatly appreciated. Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

橘香 2024-12-14 21:03:46

尝试:

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

Try:

let row n v = map (\x -> if x == v then 1 else 0) [1..n]
甚是思念 2024-12-14 21:03:46

这里有一个“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 相同。

Here a "monadic" solution:

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

The replicate function repeats a given value a number of times, e.g. replicate (v-1) 0 gives a list of v-1 zeros. The uncurry is used to modify the replicate in order to accept a tuple instead of two single arguments. The funny operator >>= is the heart of a monad; for lists it is the same as concatMap with flipped arguments.

枫林﹌晚霞¤ 2024-12-14 21:03:46

提供全面的列表:

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

或使用 fromEnum (感谢 dave4420)

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

With a comprehensive list :

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

Or using fromEnum (thanks dave4420)

 row n v = [fromEnum (x == v) | x <- [1..n]]
∞梦里开花 2024-12-14 21:03:46

这也应该有效:

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

This should also work:

row n v = replicate (v-1)­ 0 ++ [1] ++ repl­icate (n-v)­ 0
初见终念 2024-12-14 21:03:46

还有另一种解决方案,递归地构建列表:

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)

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)
清音悠歌 2024-12-14 21:03:46

具有两个临时变量 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 ] )

~

A simple recursive loop with two temporary variables c and lst . c is for counting and lst is list which we have to return.

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 ] )

~
~

网名女生简单气质 2024-12-14 21:03:46

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

the fun with haskell is that it let's you write your program very much the way you would express the algorithm. 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.
Then you check if the number is divisible by v, if it is, 1 is inserted in the output list, if not 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

小霸王臭丫头 2024-12-14 21:03:46

我喜欢基于 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应该是什么,而不是试图写下函数的作用。回想起一个关于鲜为人知的编程语言萨特的众所周知的笑话,人们可以说在纯函数式编程中,函数什么也不做,它们只是

I like to demonstrate a top down approach, based on Chris's solution:

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 n v is supposed to be, rather than trying to write down what a function does. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文