给出如下列表:
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]
答案 0 :(得分: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
的{{1}}函数:
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
或者,我们可以简单地使用标准库函数isInfixOf
。 ;)
import Data.List (isPrefixOf, tails)
contains :: Eq a => [a] -> [a] -> Bool
contains sub = any (sub `isPrefixOf`) . tails
答案 1 :(得分:6)
我会推荐Data.List
中的isInfixOf
功能。找到序列就像
let hasSequence = [7,8,9] `isInfixOf` list
答案 2 :(得分: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))
答案 3 :(得分: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