我想编写一个函数来检查一个列表是否是另一个列表的子列表。我写了这个,但它不起作用,但我猜需要这样的东西。谢谢你的帮助。
subList :: Eq a => [a] -> [a] -> Bool
subList _ [] = False
subList [] _ = True
subList (x:xs) (y:ys) =
x == y = subList xs ys
otherwise = subList (x:xs) ys
答案 0 :(得分:2)
您的代码即将开始工作,但只需要进行一些小的更改。正如其他人在评论中所说,你需要包含|
模式保护,并从第一个函数调用中删除=
。以下是最后3行应该是什么样的:
subList (x:xs) (y:ys)
| x == y = subList xs ys
| otherwise = subList (x:xs) ys
这将大部分修复您的代码,但您还需要添加基本案例subList [] [] = True
,因为空列表[]
是另一个空列表{{1}的子列表},就像[]
是[1]
的子列表一样。
添加这些更改后,您的代码将如下所示:
[1]
一些示例电话:
subList :: Eq a => [a] -> [a] -> Bool
subList [] [] = True
subList _ [] = False
subList [] _ = True
subList (x:xs) (y:ys)
| x == y = subList xs ys
| otherwise = subList (x:xs) ys
然而,他们的问题是这样的:
Prelude> subList [] []
True
Prelude> subList [1] [1,2,3]
True
Prelude> subList [1] [4,2,3]
False
Prelude> subList [1] []
False
Prelude> subList [1,2] [1,2]
True
Prelude> subList [1,2] [2,1]
False
Prelude> subList [1,2] [1,2,2,1]
True
暗示Prelude> subList [1,3] [1,2,3]
True
是[1,3]
的子列表。这可能是有意的,但如果不是,那么你需要改变你的方法。
另一种方法:
对于您的两个列表[1,2,3]
和xs
,您可以将ys
拆分为长度为ys
的子列表,让我们说xs
,并检查如果subys
中存在xs
。为此,您可以使用splitAt
,它会按subys
个字符拆分列表。这是一个示例函数:
n
如果您不想使用split_lists :: Int -> [a] -> [[a]]
split_lists _ [] = []
split_lists n xs
| length first == n = first : restxs
| otherwise = restxs
where (first, rest) = splitAt n xs
restxs = split_lists n (tail first ++ rest)
,可以执行以下操作:
splitAt
其行为如下:
split_lists :: Int -> [a] -> [[a]]
split_lists _ [] = []
split_lists n xs = filter (\x -> length x == n) list
where list = take n xs : split_lists n (drop 1 xs)
然后您可以使用any
来检查第一个列表是否存在于拆分为子列表的第二个列表中,或者您可以使用正常的递归,由您决定。
以下是使用Prelude> split_lists 3 [1,2,3,4,5,6,7,8,9,10]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8,9],[8,9,10]]
的示例:
any
以下是使用递归的示例:
subList :: (Eq a) => [a] -> [a] -> Bool
subList [] [] = True
subList xs ys = any (==xs) subys
where subys = (split_lists (length xs) ys)
现在表现如下:
subList :: (Eq a) => [a] -> [a] -> Bool
subList [] [] = True
subList xs ys = check_lists xs subys
where subys = (split_lists (length xs) ys)
check_lists :: (Eq a) => [a] -> [[a]] -> Bool
check_lists _ [] = False
check_lists xs (y:ys)
| xs == y = True
| otherwise = check_lists xs ys
答案 1 :(得分:2)
您可以像这样使用函数相交:
相交[list1] [list2] == [list1]
divs
您将为此导入Data.List。