Haskell中的三角形列表?

时间:2013-10-06 20:28:40

标签: list haskell ghci triangular

我必须编写一个函数(不使用预加载的函数)来决定某个Int列表是否为三角形,而三角形我是指它是否增加到一定数量然后减少,例如:

[2,4,5,7,4,3]还有:[],[1],[1,1],[1,2,3],[3,2,1],[1] ,2,2],[2,2,1](所以非严格增加和减少)

我想出了这个,但我不知道接下来该做什么,任何建议都表示赞赏:

ex :: [Int] -> Bool
ex [] = True
ex (x:xs) | 

2 个答案:

答案 0 :(得分:4)

只是为了好玩,我想我会把一种风味迥异的解决方案放在一起。想象一下,当数字减少时,我们有一个字符串L而不是数字列表,当它们保持不变时我们有一个E,或者当它们保持不变时我们有一个G大。然后是三角形意味着测试该字符串是否使用常规语言[LE]*[GE]*。这就是我们在这个解决方案中要做的事情:编写正则表达式并检查数字的摘要是否与之匹配。我正在使用regex-applicative,但如果您愿意,可以使用自己喜欢的正则表达式库。

{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.Maybe
import Text.Regex.Applicative

triangular = many (sym LT <|> sym EQ) *> many (sym GT <|> sym EQ)
summarize xs = zipWith compare xs (tail xs)

ex = isJust . match triangular . summarize

我们可以在ghci中的所有示例中尝试:

*Main> map ex [[2,4,5,7,4,3], [], [1], [1, 2, 3], [3, 2, 1], [1, 2, 2], [2, 2, 1]]
[True,True,True,True,True,True,True]
*Main> ex [2,3,4,3,2,3,4] -- plus one I made up to check it's not const True
False

答案 1 :(得分:3)

我会在开发时尝试解释一些代码。问题显然可以分为两部分:检测列表的增加部分和列表的减少部分。在Haskell中使用列表的关键思想是你(如果你还没有空列表)总是查看列表的 head tail ,你通常会尝试按顺序浏览列表。

因此,让我们编写一个函数来检测列表是否先严格减少。当然,有几种方法可以做到这一点。让我们尝试一种没有额外参数的递归方法。你已经有了一个好的开始

dec :: [Int] -> Bool
dec [] = True

现在让我们继续模式匹配。下一个非空的列表是包含一个元素的列表,显然总是在减少:

dec [x] = True

下一步很有意思。如果我们在开头有一个包含两个元素(xy)的列表(可能更多),那么对于要减少的列表,显然x >= y需要保持,但也从y开始的剩余列表需要减少。这就足够了,我们只需要写出来

dec (x:y:rest) = x >= y && dec (y:res)

就是这样!

现在到你的运动功能,哪里可以做同样的事情。唯一的区别是一旦列表无法增加,我们允许检查列表是否可能从此时开始减少:

ex :: [Int] -> Bool
ex [] = True
ex [x] = True
ex (x:y:rest) = (x <= y && ex (y:res)) || dec (x:y:rest)

我希望解释我是如何编写该代码的,这有助于您进行下一步练习。另请注意,还有许多其他更有效的方法可以解决这个问题。