Haskell 告诉列表是否按顺序包含某些信息
给出如下列表:Haskell 告诉列表是否按顺序包含某些信息,haskell,Haskell,给出如下列表: let list = [1,2,3,4,5,6,7,8,9,10] 我试图找到一种方法来检测列表中是否按顺序存在7,8,9,如果存在,只需打印“success”,否则打印“fail” 我正在尝试使用zip作为索引来实现这一点。有人能告诉我,我是否走上了正确的道路,或者是否有更好的方法来实现这一点 zip [0..] list 然后是这样的: [if (snd x)== 7 && let index = (fst x)
let list = [1,2,3,4,5,6,7,8,9,10]
我试图找到一种方法来检测列表中是否按顺序存在7,8,9
,如果存在,只需打印“success”,否则打印“fail”
我正在尝试使用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]
[if(snd x)=
7&&let索引=(fst x)
&&(snd x)==8&(fst x)==(指数+1)
&&(snd x)==9&(fst x)==(指数+2)
然后是“成功”
否则“失败”| x这个怎么样
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))
我建议使用Data.List
中的函数。查找序列非常简单
let hasSequence = [7,8,9] `isInfixOf` list
当试图找出一个列表算法时,通常最好从
考虑一下列表标题中的特殊情况。在这种情况下,你会怎么做
测试列表是否以[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
现在,如果我们想进一步推广它,找到任何子序列,我们可以使用
Data.List
中的isPrefixOf
函数:
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
或者,我们可以简单地使用标准库函数
我不确定您是否还想计算某些元素按给定顺序出现,但在它们之间有其他元素的情况。似乎其他答案只计算[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'
现在
和往常一样,当您不确定这些类型的实用程序函数是否存在时,它非常适合查找它们。在这种情况下,我们需要一个函数,该函数包含两个列表,并返回其中一个是否是另一个的子列表。该类型签名将是[a]->[a]->Bool
,事实上,当我们在Hoogle中输入时,isInfixOf
位于。
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