2014-10-06 75 views
4

我有一个练习要做,但是由于我对这门语言很陌生,因此我找不到任何有关如何去做的方法。Haskell函数测试一个列表是否重复(重复)元素

我有这个功能“重复”,这是根据本段给出的定义。它接收一个Int列表并返回一个Bool值。它应该检查列表是否有任何重复的元素。如果是这样,那就是真的,如果不是的话,那是假的。还有一件事:我必须通过递归定义函数,所以它必须是递归函数。将不胜感激任何帮助。

repeated :: [Int] -> Bool 

EDIT1:到目前为止,我只设法只有这一数额的代码

repeated :: [Int] -> Bool 
repeated [] = False 
repeated (h:t) = 

这使我回空单成功。其余的,我至今还没有弄清楚......

编辑2:忘记单数名单...此外,可能的答案?

repeated :: [Int] -> Bool 
repeated [] = False 
repeated [_] = False 
repeated (h:t) = if elem h t then True 
          else repeated t 

这几乎就是它。我编译过.hs,它工作的很好。谢谢大家的建议和提示! :)

+1

这是排序还是允许您先排序? – Carsten 2014-10-06 13:59:27

+0

Carsten,我认为它已经排序了。它没有指定,但是... – darkwing 2014-10-06 14:03:29

+0

@CarstenKönig如果列表是无限的呢?你仍然可以编写这个函数来终止一个无限的列表(假设它有重复的),那么不需要先排序。 – bheklilr 2014-10-06 14:06:19

回答

4

您想查找列表是否有重复项。这意味着你必须跟上你已经访问的元素列表,以便你可以检查这个元素。因此,首先,写检查的功能,如果在已访问值的列表中存在一个元素:

alreadyVisited :: Int -> [Int] -> Bool 
alreadyVisited x [] = False 
alreadyVisited x (v:visited) = ??? 

(注:这是被称为前奏elem,但你应该能够实现它自己,和这是很好的做法)

然后,您将需要编写循环遍历目标列表中所有元素的主函数,构建一组访问元素直至找到重复元素。一旦找到重复,该功能可以退出而不检查列表的其余部分。

-- Using a helper hides the fact that the visited list is needed 
repeated :: [Int] -> Bool 
repeated xs = go xs [] 
--     ^-- initial visited list is empty 
    where 
     -- same base case that you came up with, 
     -- an empty list does not have duplicate elements 
     go [] _ = False 
     -- The recursive step, think about what you need this function to do 
     go (x:xs) visited = 
      if alreadyVisited x visited 
       then ???  -- If it's already visited, do what? 
       else ???  -- Otherwise? 

这里我刚刚建立了结构为你,你必须填写自己的详细信息。请记住,这是而不是一个有效的实施,尤其是因为alreadyVisited将变得如此缓慢,但如果您对速度感兴趣,那么您可以将访问列表替换为Data.Set.Set,它具有更好的性能查找时间。

+0

如果它只是知道列表是否包含重复项,则可以使用Data.List中的nub函数,如下所示:'hasDup l = nub l == l'(nub删除所有重复项...所以只有在列表中没有重复项。) – Chris 2017-04-19 20:48:00

2

这是我对这个方法(使用设置和比较长)

import qualified Data.Set as Set -- From the 'containers' library 

hasDuplicates :: (Ord a) => [a] -> Bool 
hasDuplicates list = length list /= length set 
    where set = Set.fromList list 

我使用的containers Haskell Package