0

给定一个类似的列表:

let list = [1,2,3,4,5,6,7,8,9,10]

我试图想出一种方法来7,8,9按顺序检测列表中是否存在,如果存在则简单地打印“成功”,否则打印“失败”。

我正在尝试使用zip索引来完成此操作。有人可以建议我是否走在正确的轨道上,或者是否有更好的方法来实现这一目标?

zip [0..] list

然后是这样的:

[if (snd x)== 
             7 && let index = (fst x) 
               && (snd x)==8 && (fst x)==(index+1) 
               && (snd x)==9 && (fst x)==(index+2) 
               then "success" 
               else "fail" | x <- list]
4

4 回答 4

8

当试图找出一个列表算法时,通常最好从考虑列表头中的特殊情况开始。在这种情况下,您将如何测试列表是否以 开头[7,8,9]

beginsWith789 :: [Int] -> Bool
beginsWith789 (7:8:9:_) = True
beginsWith789 _         = False

即我们可以只对前三个元素进行模式匹配。现在概括一下,如果我们在列表头中没有找到子序列,我们递归地检查列表的尾部

contains789 :: [Int] -> Bool
contains789 (7:8:9:_) = True
contains789 (_:xs)    = contains789 xs
contains789 _         = False

现在,如果我们想进一步推广它以找到任何子序列,我们可以使用isPrefixOf函数 from Data.List

import Data.List (isPrefixOf)

contains :: Eq a => [a] -> [a] -> Bool
contains sub lst | sub `isPrefixOf` lst = True
contains (_:xs)  = contains sub xs
contains _       = False

any我们可以通过使用和tails检查列表的任何连续较短的尾部是否以给定的子序列开头来整理它:

import Data.List (isPrefixOf, tails)

contains :: Eq a => [a] -> [a] -> Bool
contains sub = any (sub `isPrefixOf`) . tails

或者,我们可以简单地使用标准库函数isInfixOf。;)

> import Data.List
> [7,8,9] `isInfixOf` [1,2,3,4,5,6,7,8,9]
True
于 2013-02-11T14:56:10.310 回答
6

我会推荐isInfixOf. Data.List查找序列很简单

let hasSequence = [7,8,9] `isInfixOf` list
于 2013-02-11T14:45:04.647 回答
1

这个怎么样?

elemIndex (7,8,9) $ zip3 list (tail list) (tail (tail list))

elemIndex 来自 Data.List。

如果你不关心它在什么索引,你可以使用这个

elem (7,8,9) $ zip3 list (tail list) (tail (tail list))
于 2013-02-11T14:41:10.450 回答
1

我不确定您是否还想计算某些元素以给定顺序出现但它们之间有一些其他元素的情况。似乎其他答案只计算[7, 8, 9]原始子列表的情况。如果你想让我们说[7,8,9]被发现在[7,0,8,0,9,0],你可以使用

appears :: (Eq a) => [a] -> [a] -> Bool
appears [] _ = True
appears _ [] = False
appears ns@(n : ns') (h : hs')
    | n == h    = appears ns' hs'
    | otherwise = appears ns hs'

现在

appears [7,8,9] [7,0,8,0,9] --> True
appears [7,8,9] [1..10]     -->  True
appears [3,8,9] [1..10]     -->  True
appears [10,8,9] [1..10]    -->  False
于 2013-02-11T15:17:47.467 回答